为什么从函数返回对象时会得到两个临时对象 这是我的C++代码< /p> class CTest { public: int number; int arr[10]; }; CTest Return(int val) { CTest obj; obj.number = val; return obj; } int main() { CTest obj = Return(10); return 0; }

为什么从函数返回对象时会得到两个临时对象 这是我的C++代码< /p> class CTest { public: int number; int arr[10]; }; CTest Return(int val) { CTest obj; obj.number = val; return obj; } int main() { CTest obj = Return(10); return 0; },c++,assembly,x86,C++,Assembly,X86,我通过查看汇编代码发现有两个临时对象 //in main CTest obj = Return(10); 0009F6CE push 0Ah 0009F6D0 lea eax,[ebp-158h] ; pass the first temporary object's address to Return 0009F6D6 push eax 0009F6D7 call Return (0822E9h) 000

我通过查看汇编代码发现有两个临时对象

//in main

    CTest obj = Return(10);
0009F6CE  push        0Ah  
0009F6D0  lea         eax,[ebp-158h]  ; pass the first temporary object's address to Return
0009F6D6  push        eax  
0009F6D7  call        Return (0822E9h)  
0009F6DC  add         esp,8  
0009F6DF  mov         ecx,0Bh  
0009F6E4  mov         esi,eax  
0009F6E6  lea         edi,[ebp-124h]  ; copy from the first temporary object
0009F6EC  rep movs    dword ptr es:[edi],dword ptr [esi]  
0009F6EE  mov         ecx,0Bh  
0009F6F3  lea         esi,[ebp-124h]  
0009F6F9  lea         edi,[obj]       ; copy from the second temporary object
0009F6FC  rep movs    dword ptr es:[edi],dword ptr [esi]

//in Return

    CTest obj;
    obj.number = val;
0009F64E  mov         eax,dword ptr [val]  
0009F651  mov         dword ptr [obj],eax  
    return obj;
0009F654  mov         ecx,0Bh  
0009F659  lea         esi,[obj]  
0009F65C  mov         edi,dword ptr [ebp+8]  
0009F65F  rep movs    dword ptr es:[edi],dword ptr [esi]  ; copy to the first temporary object
0009F661  mov         eax,dword ptr [ebp+8]  
为什么我得到了第二个临时对象。似乎只有一个临时对象就足够了。如果我添加一个空的析构函数
~CTest(){}
将不会有一个临时对象(RVO?)

“为什么我得到了第二个临时对象”

这可能是因为您关闭了优化

否则,编译器将通过将main中的
obj
作为隐藏参数(就像
this
指针)传递给返回函数来进行优化,并将“结果”分配给它

因此,优化后,您的代码将如下所示:

void Return(void* put_result_here , int val) {
    CTest obj;
    obj.number = val;
    put_result_here = obj;
}


int main() {
    CTest obj; 
    Return(&obj , 10);
    return 0;
}

这种优化称为按值返回优化

它是返回和赋值(复制)。您的编译器显然没有执行复制省略。您是否使用优化编译代码?使用优化,我的编译器将main编译为:
xor eax,eax;ret
。谢谢您的评论。是的,我正在调试模式下学习汇编,没有优化。第一个临时文件用于返回,第二个临时文件用于赋值,对吗?这是哪个编译器?是msvc吗?转换不会用赋值代替构造。代码看起来更像:
(void*)把结果放在这里
{obj=*(new(把结果放在这里)CTest);obj.number=val;}
,但是在
main
中不会有
obj
的构造。试图为此编写伪代码(IMHO)是非常误导的。