我注意到构造函数会在返回之前将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;
}
答案 0 :(得分:1)
你的第二个问题不同意你的第一个问题。如果new
产生条件结果,if ( operator new() == 0 ) return 0; else return constructor();
如何使用constructor()
?
总之...
编译器对寄存器的作用是编译器的业务。寄存器倾向于保存任何立即有用的信息,并且如果编译器被认为每次使用构造函数时都会立即使用该对象,则可以合理地选择将this
放入寄存器中。 / p>
ABI可能要求施工人员这样做,但我怀疑有没有。无论如何,这些协议仅适用于从库中导出的内容,而不仅仅适用于程序中。
在继续初始化对象之前,任何new
表达式都会检查operator new
对0
的结果。 operator new
可能会通过返回nullptr
(或NULL
等)来表示失败。
这实际上是放置新表达式的问题,因为它表示不可避免的运行时开销,因为通常已知给定指针是非空的。
答案 1 :(得分:0)
这可以是设计的一个特征,在C ++和其他语言中,返回对给定实例的引用允许更多"惯用"使用对象本身提供的功能,简而言之就是Named parameter Idiom。
但这只是一个选项,它有时会很有用,特别是如果你能够以一种只采取行动的方式设计你的图书馆"无需传递大量参数,因此方法调用链保持可读性。