[英]Why doesn't the destructor get called on objects you are returning?
因此,据我了解,您可以通过返回指向C ++的指针来返回对象。 但是我给人的印象是,一旦函数运行完毕,析构函数将在所有对象上调用。 为什么不对要返回的对象调用析构函数?
当那些对象离开其作用域时,仅调用具有自动存储持续时间的对象的析构函数(不仅仅是函数,而是任何作用域:大括号, for
语句,甚至单行表达式)。
另一方面, 静态存储持续时间的对象仅在程序退出时销毁,而动态存储持续时间的对象(即使用new
运算符创建的对象)仅在您的请求下被手动销毁。
当您以描述的方式返回指针时,几乎可以肯定该指针指向动态创建的对象,因此,指针的接收者有责任确保最终清除该对象。 这是裸指针的最大缺点:它们不传递任何隐式的所有权声明,并且您必须在代码外部手动提供有关谁负责动态对象的信息。
使用new
创建的对象的析构函数只有在delete
指针后才会被调用。
为了确保您不会忘记删除指针,请尝试使用智能指针,例如std::shared_ptr
或std::unique_ptr
。
如果您的编译器不够新颖,无法包含智能指针,则可以从Boost中找到一些内容。
当您返回对对象的引用时,该引用将不再作用于函数,因此不会随函数失效(即,不会删除指向对象的指针)。
仅当您错误编写代码时,才会发生这种情况。 例如:
Foo* MyFunction()
{
Foo foo(2);
return &foo;
} // foo is implicitly destroyed as we return
这已破了。 我使用foo
的地址,但是由于超出范围,它也被破坏了。 这可以:
Foo* MyFunction()
{
Foo* j=new Foo(2);
return j;
} // j is implicitly destroyed as we return
这可以。 尽管j
由于超出范围而被销毁,但我返回的值仍然是我创建的Foo
的地址。 我分配的foo
不会被销毁,因为它不会超出范围。
有两种分配对象的方法:堆栈和堆。
1)使用new
关键字在堆上创建对象。 这些对象在被delete
之前不会被破坏d。
2) 堆栈上还存在其他对象-没有new
,也没有delete
。 这些对象超出范围时将被销毁。 如果您返回指向这些对象之一的指针(通过获取堆栈分配的对象的地址,则一旦该对象超出范围,该指针将无效。
C ++(。net外部)在您告知对象之前不会删除对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.