3

自动指针一旦超出范围,就会在内部调用它指向的对象的删除。如果我们分配一个在堆上创建的对象,这可以正常工作。但是,如果我尝试分配一个不是在堆上创建的对象,它会崩溃,因为 delete 被调用了两次。首先是 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 仅保存在堆上创建的对象?

4

5 回答 5

3

是的,确切地说,您只能auto_ptr用于堆分配的对象。技术原因是auto_ptr析构函数调用delete和调用delete未在堆上分配的对象是未定义的行为,这可能会使堆崩溃,多次运行析构函数,以及其他任何你不应该指望和不应该推测的事情。

于 2012-05-16T11:43:28.140 回答
2

简短的回答 - 是的。

这意味着您将管理内存的责任传递给auto_ptr. 但是,如果您在自动存储中创建对象,则该责任在于运行时,因此您不能放弃。

于 2012-05-16T11:42:54.830 回答
2

自动存储持续时间的对象(您所谓的“在堆栈上”)会自动清理。auto_ptr存在以便于清理分配的对象new(它调用delete指针)。与自动存储持续时间的对象一起使用是没有意义auto_ptr的,因为它们没有分配给new.

于 2012-05-16T11:43:16.067 回答
2

如果您使用 std::auto_ptr 您只能保存在堆上创建的对象。

但是,如果您使用例如 boost::shared_ptr 您可以指定一个删除器,当对象离开范围时将调用该删除器。因此,如果您引用堆栈上的对象,您可以使用实际上什么都不做的自定义删除器。有关详细信息,
请参见boost::shared_ptr

std::auto_ptr 自 C++11 起已弃用
请参阅C++11 std::auto_ptr deprecated

于 2012-05-16T11:52:28.280 回答
1

这是否意味着我们可以使用auto_ptr仅保存在堆上创建的对象?
是的。
自动对象会自动销毁,因此它们不需要像智能指针这样的包装器。

请注意,您可以使用,shared_ptr或者unique_ptr它可以让您方便地调用您的自定义删除函数。您可以使用自定义内存分配器而不是new使用此自定义删除器功能。

auto_ptr已弃用,C++ 标准建议unique_ptr它是更好的选择。

于 2012-05-16T11:43:33.443 回答