我当时在想,当一个函数将堆栈上的一个对象返回给调用函数时,调用函数将获得原始对象的副本,但是一旦堆栈解散,就会调用原始对象的析构函数。但是在以下程序中,析构函数仅被调用一次。我希望它会被两次调用。
#include <iostream>
class MyClass
{
public:
~MyClass() { std::cout << "destructor of MyClass" << std::endl; }
};
MyClass getMyClass()
{
MyClass obj = MyClass();
return obj; // dtor call for obj here?
}
int main()
{
MyClass myobj = getMyClass();
return 0; // Another dtor call for myobj.
}
但是“MyClass的析构函数”仅被打印一次。我的假设是错误的还是这里发生了其他事情?
最佳答案
在一种特殊情况下,允许编译器优化副本:这称为named return value optimization(NRVO)。基本上,编译器为调用站点上的返回对象分配内存,并让函数直接填充该内存,而不是在被调用站点上创建对象并将其复制回去。现代的编译器会在可能的情况下定期执行此操作(在某些情况下,这并不容易,因为函数中有多个返回路径可返回不同的实例)。