繁体   English   中英

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

[英]Why doesn't the destructor get called on objects you are returning?

因此,据我了解,您可以通过返回指向C ++的指针来返回对象。 但是我给人的印象是,一旦函数运行完毕,析构函数将在所有对象上调用。 为什么不对要返回的对象调用析构函数?

当那些对象离开其作用域时,仅调用具有自动存储持续时间的对象的析构函数(不仅仅是函数,而是任何作用域:大括号, for语句,甚至单行表达式)。

另一方面, 静态存储持续时间的对象仅在程序退出时销毁,而动态存储持续时间的对象(即使用new运算符创建的对象)仅在您的请求下被手动销毁。

当您以描述的方式返回指针时,几乎可以肯定该指针指向动态创建的对象,因此,指针的接收者有责任确保最终清除该对象。 这是裸指针的最大缺点:它们不传递任何隐式的所有权声明,并且您必须在代码外部手动提供有关谁负责动态对象的信息。

使用new创建的对象的析构函数只有在delete指针后才会被调用。

为了确保您不会忘记删除指针,请尝试使用智能指针,例如std::shared_ptrstd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM