考虑以下最小代码:
class MyClass {
public:
MyClass() {}
};
MyClass myfunc() {
MyClass obj;
cout << "Address of obj in myFunc " << &obj << endl;
return obj;
}
int main() {
MyClass obj(myfunc());
cout << "Address of obj in main " << &obj << endl;
return 0;
}
我获得以下输出:
Address of obj in myFunc 0x7fff345037df
Address of obj in main 0x7fff3450380f
现在,只需在MyClass中添加析构函数,我就得到以下输出:
Address of obj in myFunc 0x7fffb6aed7ef
Address of obj in main 0x7fffb6aed7ef
显示两个对象现在都相同......这只是巧合吗?!
此外,究竟发生了什么:
MyClass obj(myfunc());
我已经重载了复制构造函数来打印消息,但它永远不会出现......
答案 0 :(得分:6)
通过添加析构函数(无论您实际执行的是什么,您都没有显示代码),行为更改为使用返回值优化,称为RVO。
然后将指向调用者存储器的指针传递给该函数,并且该函数直接在该存储器中构造该对象,而不是例如复制处理器寄存器或寄存器组中的值。
在没有RVO的情况下,也可以使用具有隐藏结果存储指针的相同调用约定。如果没有RVO,则在功能结束时执行复制或移动。该标准在某些条件下支持RVO优化,但是,虽然可以合理地预期,但编译器没有义务执行RVO。