简体   繁体   English

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

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

So as I understand it you can return objects in C++ by returning pointers to them. 因此,据我了解,您可以通过返回指向C ++的指针来返回对象。 But I was under the impression that once a function is finished running, the destructor gets called on all the objects. 但是我给人的印象是,一旦函数运行完毕,析构函数将在所有对象上调用。 Why doesn't the destructor get called on the object you're returning? 为什么不对要返回的对象调用析构函数?

Only the destructors of objects with automatic storage duration are called when those objects leave their scope (not just a function, but any scope: braces, for -statements, even single-line expressions). 当那些对象离开其作用域时,仅调用具有自动存储持续时间的对象的析构函数(不仅仅是函数,而是任何作用域:大括号, for语句,甚至单行表达式)。

On the other hand, objects of static storage duration are only destroyed at program exit, and objects of dynamic storage duration (ie those created with a new operator) only get destroyed manually on your request. 另一方面, 静态存储持续时间的对象仅在程序退出时销毁,而动态存储持续时间的对象(即使用new运算符创建的对象)仅在您的请求下被手动销毁。

When you return a pointer in the way you describe, then almost surely that pointer points to a dynamically created object, and thus it is the responsibility of the recipient of the pointer to see to it that the object is eventually cleaned up. 当您以描述的方式返回指针时,几乎可以肯定该指针指向动态创建的对象,因此,指针的接收者有责任确保最终清除该对象。 This is the great disadvantage of naked pointers: They do not convey any implicit ownership statement, and you have to provide the information about who's responsible for the dynamic object manually outside the code. 这是裸指针的最大缺点:它们不传递任何隐式的所有权声明,并且您必须在代码外部手动提供有关谁负责动态对象的信息。

The destructor for an object you created with new doesn't get called until you delete the pointer. 使用new创建的对象的析构函数只有在delete指针后才会被调用。

To make sure you don't forget to delete the pointer, try using smart pointers such as std::shared_ptr or std::unique_ptr . 为了确保您不会忘记删除指针,请尝试使用智能指针,例如std::shared_ptrstd::unique_ptr

If your compiler isn't new enough to include smart pointers, you can find some from Boost . 如果您的编译器不够新颖,无法包含智能指针,则可以从Boost中找到一些内容。

当您返回对对象的引用时,该引用将不再作用于函数,因此不会随函数失效(即,不会删除指向对象的指针)。

That would only happen if you wrote code incorrectly. 仅当您错误编写代码时,才会发生这种情况。 For example: 例如:

Foo* MyFunction()
{
    Foo foo(2);
    return &foo;
} // foo is implicitly destroyed as we return

This is broken. 这已破了。 I take the address of foo , but it is also destroyed because it goes out of scope. 我使用foo的地址,但是由于超出范围,它也被破坏了。 This is fine: 这可以:

Foo* MyFunction()
{
    Foo* j=new Foo(2);
    return j;
} // j is implicitly destroyed as we return

This is fine. 这可以。 While j is destroyed because it goes out of scope, the value that I returned is still the address of the Foo I created. 尽管j由于超出范围而被销毁,但我返回的值仍然是我创建的Foo的地址。 The foo that I allocated will not be destroyed because it doesn't go out of scope. 我分配的foo不会被销毁,因为它不会超出范围。

There are two ways of allocating objects: the stack and the heap. 有两种分配对象的方法:堆栈和堆。

1) Objects are created on the heap with the new keyword. 1)使用new关键字在堆上创建对象。 These objects are not destroyed until they are delete d. 这些对象在被delete之前不会被破坏d。

2) Other objects exist on the stack - no new , no delete . 2) 堆栈上还存在其他对象-没有new ,也没有delete These objects are destroyed when they go out of scope. 这些对象超出范围时将被销毁。 If you return a pointer to one of these objects (by taking the address of a stack-allocated object, the pointer will be invalid once the object has gone out of scope. 如果您返回指向这些对象之一的指针(通过获取堆栈分配的对象的地址,则一旦该对象超出范围,该指针将无效。

C ++(。net外部)在您告知对象之前不会删除对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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