一旦超出范围,自动指针在内部调用它指向的对象上的删除。如果我们分配在堆上创建的对象,这可以正常工作。但是如果我尝试分配一个不是在堆上创建的对象,它会崩溃,因为删除会被调用两次。首先是auto_ptr本身,第二个是当对象超出范围时,它的析构函数再次被调用。 如下图所示,
#include <iostream>
#include <memory>
using namespace std;
class sample
{
public:
sample() { puts("sample"); }
~sample() { puts("~sample"); }
};
int main()
{
sample sObj;
auto_ptr<sample> samplePtr(&sObj);
}
这是否意味着我们可以使用auto_ptr仅保存在堆上创建的对象?
答案 0 :(得分:3)
是的,确切地说,您只能将auto_ptr
用于堆分配的对象。技术原因是auto_ptr
析构函数调用delete
并且对未在堆上分配的对象调用delete
是未定义的行为,这会导致堆崩溃,多次运行析构函数,你不应该指望的任何其他事情,不应该推测。
答案 1 :(得分:2)
简短回答 - 是的。
这意味着您将管理内存的责任传递给auto_ptr
。但是如果你在自动存储中创建对象,那么责任在于运行时,所以你不能放弃它。
答案 2 :(得分:2)
自动清理对象(您在堆栈中称为“对象”)的对象会自动清理。存在auto_ptr
以便于清理使用new
分配的对象(它在指针上调用delete
)。将auto_ptr
用于具有自动存储持续时间的对象是没有意义的,因为它们未与new
一起分配。
答案 3 :(得分:2)
如果使用std :: auto_ptr,则只能保存在堆上创建的对象。
但是如果你使用例如boost :: shared_ptr,你可以指定一个删除器 当对象离开范围时调用。因此,如果您在堆栈上引用对象,则可以 使用实际上什么都不做的自定义删除器 有关详细信息,请参阅boost::shared_ptr
std :: auto_ptr从C ++ 11开始不推荐使用 见C++11 std::auto_ptr deprecated
答案 4 :(得分:1)
这是否意味着我们可以使用auto_ptr
来仅保存在堆上创建的对象?
是的。
自动对象会自动销毁,因此它们不需要像智能指针那样的任何包装器。
请注意,您可以使用shared_ptr
或unique_ptr
,这样您就可以调用自定义deletor函数。通过使用此自定义deletor功能,您可以使用自定义内存分配器而不是new
。
auto_ptr
已被弃用,C ++标准建议unique_ptr
是更好的选择。