Почему конструкторы "возвращают" этот указатель?

Я заметил, что перед возвратом конструктор переместит 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 вариант, иногда это может быть полезно, особенно если вы можете создать свою библиотеку так, чтобы она "принимала действия" без необходимости передавать значительное количество параметров, поэтому цепочка вызовов методов остается читаемым.