为什么构造函数“返回”这个指针?

时间:2013-07-31 03:16:33

标签: c++

我注意到构造函数会在返回之前将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;
}

2 个答案:

答案 0 :(得分:1)

你的第二个问题不同意你的第一个问题。如果new产生条件结果,if ( operator new() == 0 ) return 0; else return constructor();如何使用constructor()

总之...

  1. 编译器对寄存器的作用是编译器的业务。寄存器倾向于保存任何立即有用的信息,并且如果编译器被认为每次使用构造函数时都会立即使用该对象,则可以合理地选择将this放入寄存器中。 / p>

    ABI可能要求施工人员这样做,但我怀疑有没有。无论如何,这些协议仅适用于从库中导出的内容,而不仅仅适用于程序中。

  2. 在继续初始化对象之前,任何new表达式都会检查operator new0的结果。 operator new可能会通过返回nullptr(或NULL等)来表示失败。

    这实际上是放置新表达式的问题,因为它表示不可避免的运行时开销,因为通常已知给定指针是非空的。

答案 1 :(得分:0)

这可以是设计的一个特征,在C ++和其他语言中,返回对给定实例的引用允许更多"惯用"使用对象本身提供的功能,简而言之就是Named parameter Idiom

但这只是一个选项,它有时会很有用,特别是如果你能够以一种只采取行动的方式设计你的图书馆"无需传递大量参数,因此方法调用链保持可读性。

相关问题