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

时间:2012-03-09 23:38:44

标签: c++

据我所知,你可以通过返回指向它们的指针来返回C ++中的对象。但我的印象是,一旦函数完成运行,就会在所有对象上调用析构函数。为什么析构函数不会被调用你正在返回的对象?

6 个答案:

答案 0 :(得分:5)

当这些对象离开其范围(不仅仅是一个函数,而是任何范围:大括号,for - 语句,甚至单个 - 时,只调用具有自动存储持续时间的对象的析构函数线表达式)。

另一方面,静态存储持续时间的对象仅在程序退出时被销毁,动态存储持续时间的对象(即使用{{1}创建的对象}}}仅在您的请求上手动销毁。

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

答案 1 :(得分:1)

使用new创建的对象的析构函数在您delete指针之前不会被调用。

为确保您不会忘记删除指针,请尝试使用智能指针,例如std::shared_ptrstd::unique_ptr

如果您的编译器不够新,无法包含智能指针,您可以从Boost找到一些。

答案 2 :(得分:1)

当你返回对象的引用时,它不再作用于该函数,因此不会死于该函数(即不会删除指向该对象的指针)。

答案 3 :(得分:1)

只有在您错误地编写代码时才会发生这种情况。例如:

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不会被销毁,因为它不会超出范围。

答案 4 :(得分:1)

分配对象有两种方法:堆栈和堆。

1)使用new关键字在上创建对象。这些对象在delete d。

之前不会被销毁

2)堆栈上存在其他对象 - 没有new,没有delete。这些对象在超出范围时会被销毁。如果返回指向其中一个对象的指针(通过获取堆栈分配的对象的地址,一旦对象超出范围,指针将无效。

答案 5 :(得分:-1)

C ++(在.net之外)在你告诉它之前不会删除它。