如果在一个函数中,我新建了一个对象,我应该在函数退出之前在指针上调用 delete 还是在函数退出后自动调用的析构函数完成删除的工作?
从函数返回时,所有具有自动存储持续时间的本地对象都被销毁。如果它们属于类类型,则在收回它们占用的存储空间之前调用它们的析构函数。如果它们是非类类型(如int
),则无需调用析构函数。
这里,唯一具有自动存储持续时间的本地对象是指针a
(注意:不是a
! 指向的对象),并且指针不是类类型。这意味着a
将被销毁,仅此而已 - 特别是,a
指向的对象不会被销毁。
因此,您必须delete
在离开函数之前调用(无论您是通过执行return
还是通过抛出异常离开它)。通常,您必须始终将每个呼叫new
与呼叫匹配delete
,并将每个呼叫new[]
与呼叫匹配delete[]
。
由于delete
在new
使用 .是本地对象,其析构函数旨在清理在构造过程中获得的资源。
例如:
void foo()
{
auto p = std::make_unique<A>(); // OK, make_unique() will only be available
// in C++14. Meanwhile, in C++11 you can do:
//
// std::unique_ptr<A> p(new A());
// Work with p...
// No memory leak here!
}
如果您不允许使用 C++11,例如因为您的老板说出于兼容性原因必须在旧版本的编译器上编译 SW,您总是可以使用Boost 的智能指针类(例如boost::shared_ptr
和boost::scoped_ptr
.
无论如何,请注意,除非需要,否则不应执行动态分配。如果您不需要它(例如,如果您不必与任何其他函数共享该对象的所有权),您可以简单地为您的A
对象提供自动存储持续时间,从而确保在超出范围时调用其析构函数:
void foo()
{
A a;
// Work with a...
// a will be destroyed when returning from foo()
}