为什么析构函数不会在您要返回的对象上调用?
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之外)不会删除对象,除非你告诉它。
- 对RValue对象调用的LValue ref限定成员函数
- 检查哪个对象调用了另一个对象的对象方法
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 从 Base 引用对象调用派生类的成员
- 为什么为未删除的对象调用析构函数?
- Qt c++不会为所有对象调用move_slot.为什么?
- 使用在堆栈上创建的对象调用虚拟函数
- 使用基类对象调用Dervied Class函数
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 从类中的对象调用类中的函数的最佳方法
- 派生对象调用的 Base 方法的模板推导
- 如何使用单个对象调用具有相同名称的两个类函数
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 如果类没有任何成员变量,则通过临时对象调用类的成员函数的开销是多少?
- 如何对动态数组中的某些对象调用析构函数
- 如何从列表中存储的对象调用成员函数
- 从线程内的对象调用静态方法
- 从成员对象调用方法
- 当包含它的对象调用其析构函数时,unique_ptr是否未分配
- 从对象调用成员对象,错误:引用非常量值的初始值必须是左值