I was thinking that when a function returns an object on the stack to the calling function, the calling function gets a copy of the original object but the original object's destructor is called as soon as the stack unwinds. But in the following program, the destructor is getting called only once. I expected it to be called twice.
我想当一个函数将堆栈中的对象返回给调用函数时,调用函数会获取原始对象的副本,但是一旦堆栈展开就会调用原始对象的析构函数。但是在下面的程序中,析构函数只被调用一次。我预计它会被调用两次。
#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.
}
But "destructor of MyClass" is getting printed only once. Is my assumption wrong or is there something else going on here?
但是“MyClass的析构函数”只打印了一次。我的假设是错的还是还有其他事情发生在这里?
1 个解决方案
#1
23
This is a special case where the compiler is allowed to optimize out the copy: this is called named return value optimization (NRVO). Basically, the compiler allocates memory for the return object on the call site and lets the function fill in that memory directly instead of creating the object at the called site and copying it back. Modern compilers do this routinely whenever possible (there are some situations where this isn't easy since there are several return paths in the function that return different instances).
这是一种特殊情况,允许编译器优化副本:这称为命名返回值优化(NRVO)。基本上,编译器为调用站点上的返回对象分配内存,并让函数直接填充该内存,而不是在被调用站点创建对象并将其复制回来。现代编译器会尽可能地执行此操作(在某些情况下,这很容易,因为函数中有多个返回路径,返回不同的实例)。
#1
23
This is a special case where the compiler is allowed to optimize out the copy: this is called named return value optimization (NRVO). Basically, the compiler allocates memory for the return object on the call site and lets the function fill in that memory directly instead of creating the object at the called site and copying it back. Modern compilers do this routinely whenever possible (there are some situations where this isn't easy since there are several return paths in the function that return different instances).
这是一种特殊情况,允许编译器优化副本:这称为命名返回值优化(NRVO)。基本上,编译器为调用站点上的返回对象分配内存,并让函数直接填充该内存,而不是在被调用站点创建对象并将其复制回来。现代编译器会尽可能地执行此操作(在某些情况下,这很容易,因为函数中有多个返回路径,返回不同的实例)。