据我所知,你可以通过返回指向它们的指针来返回C ++中的对象。但我的印象是,一旦函数完成运行,就会在所有对象上调用析构函数。为什么析构函数不会被调用你正在返回的对象?
答案 0 :(得分:5)
当这些对象离开其范围(不仅仅是一个函数,而是任何范围:大括号,for
- 语句,甚至单个 - 时,只调用具有自动存储持续时间的对象的析构函数线表达式)。
另一方面,静态存储持续时间的对象仅在程序退出时被销毁,动态存储持续时间的对象(即使用{{1}创建的对象}}}仅在您的请求上手动销毁。
当您按照描述的方式返回指针时,几乎可以肯定该指针指向动态创建的对象,因此指针的接收者有责任确保该对象最终被清除。这是裸指针的最大缺点:它们不传达任何隐含的所有权声明,并且您必须在代码之外手动提供有关谁负责动态对象的信息。
答案 1 :(得分:1)
使用new
创建的对象的析构函数在您delete
指针之前不会被调用。
为确保您不会忘记删除指针,请尝试使用智能指针,例如std::shared_ptr
或std::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之外)在你告诉它之前不会删除它。