Почему конструкторы "возвращают" этот указатель?
Я заметил, что перед возвратом конструктор переместит this
в eax
. Это возвращаемое значение или что-то еще?
class CTest {
int val_;
public:
CTest() {
0093F700 push ebp
0093F701 mov ebp,esp
0093F703 sub esp,0CCh
0093F709 push ebx
0093F70A push esi
0093F70B push edi
0093F70C push ecx
0093F70D lea edi,[ebp-0CCh]
0093F713 mov ecx,33h
0093F718 mov eax,0CCCCCCCCh
0093F71D rep stos dword ptr es:[edi]
0093F71F pop ecx
0093F720 mov dword ptr [this],ecx
val_ = 1;
0093F723 mov eax,dword ptr [this]
0093F726 mov dword ptr [eax],1
}
0093F72C mov eax,dword ptr [this]
0093F72F pop edi
0093F730 pop esi
0093F731 pop ebx
0093F732 mov esp,ebp
0093F734 pop ebp
0093F735 ret
Режим отладки VS2012
Я обнаружил, что new
будет использовать свое "возвращаемое значение". Похоже, if(operator new() == 0) return 0; else return constructor();
class CTest {
int val_;
public:
CTest() {
val_ = 1;
__asm {
mov eax, 0x12345678
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
}
}
};
int main() {
CTest *test = new CTest; // test == 0x12345678
return 0;
}
Ответы
Ответ 1
Ваш второй вопрос не согласуется с вашим первым. Как new
использовать if ( operator new() == 0 ) return 0; else return constructor();
, если constructor()
создает результат условия?
В любом случае...
-
Что делает компилятор с регистрами - это бизнес компилятора. Регистры имеют тенденцию удерживать любую информацию сразу же полезной, и если компилятор написан с убеждением, что каждый раз, когда используется конструктор, этот объект используется сразу же после этого, он может разумно выбрать поместить this
в регистр.
Для ABI могут потребоваться конструкторы, но я сомневаюсь, что это произойдет. В любом случае, такие протоколы применяются только к вещам, экспортированным из библиотек, а не строго в программы.
-
Любое выражение new
проверяет результат operator new
на 0
, прежде чем приступать к инициализации объекта. operator new
может сигнализировать об ошибке, возвращая nullptr
(или NULL
и т.д.).
Это может быть проблема с размещением новых выражений, поскольку она представляет собой неизбежную служебную нагрузку во время выполнения, поскольку данный указатель, как правило, уже известен как ненулевой.
Ответ 2
Это может быть функция по дизайну, на С++ и других языках, возвращая ссылку на данный экземпляр, позволяет более "идиоматическое" использование функций, предлагаемых самим объектом, короче говоря, Именованный параметр Idiom.
Но это всего лишь 1 вариант, иногда это может быть полезно, особенно если вы можете создать свою библиотеку так, чтобы она "принимала действия" без необходимости передавать значительное количество параметров, поэтому цепочка вызовов методов остается читаемым.