为什么析构函数不是从函数中调用返回的对象?

时间:2009-03-30 16:11:38

标签: c++ memory-management destructor

我在想,当一个函数将堆栈中的对象返回给调用函数时,调用函数会获取原始对象的副本,但是一旦堆栈展开就会调用原始对象的析构函数。但是在下面的程序中,析构函数只被调用一次。我预计它会被召唤两次。

#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的析构函数”只打印了一次。我的假设是错的还是还有其他事情发生在这里?

1 个答案:

答案 0 :(得分:25)

这是一种特殊情况,允许编译器优化副本:这称为named return value optimization(NRVO)。基本上,编译器为调用站点上的返回对象分配内存,并让函数直接填充该内存,而不是在被调用站点创建对象并将其复制回来。现代编译器会尽可能地执行此操作(在某些情况下这并不容易,因为函数中有多个返回不同实例的返回路径)。