C ++制作和销毁unique_ptr指针

时间:2016-01-25 09:38:39

标签: c++ pointers

我正在学习如何使用std::unique_ptr指针。 我的代码:

#include <iostream>
#include <memory>

class object{
public:
    void say(){
            std::cout<<"hi";
    }
};

int main(){
      std::unique_ptr<object> p = 
                  std::unique_ptr<object>(new object);
      p->say();
}

我的问题是:

  1. 我正确使用std::unique_ptr吗?

  2. 如何删除或删除此(p)指针,以便没有内存使用或泄漏?

5 个答案:

答案 0 :(得分:7)

std::unique_ptr<object> p = std::unique_ptr<object>(new object);

这很好,但你可以这样简化:

std::unique_ptr<object> p { new object{} };

或者在C ++ 14中这样:

auto p = std::make_unique<object>();

您不需要delete std::unique_ptr,这就是重点。当p超出范围时(在main的末尾),指针对象将自动delete

也就是说,在这个例子中没有必要使用动态分配。您应该只使用自动变量:

int main(){
      object p{};
      p.say();
}

一个好的经验法则是尽可能使用自动存储持续时间,并在必要时使用动态存储持续时间。

std::make_unique具有在以下情况下防止泄漏的优势:

process(std::unique_ptr<object>(new object), iMightThrow());

如果先执行new object,那么iMightThrow运行并抛出,内存将被泄露。 std::make_unique防范此事:

process(std::make_unique<object>(), iMightThrow());

现在如果iMightThrow()抛出,std::unique_ptr将不会被创建,或者它将被销毁并回收内存。

答案 1 :(得分:2)

std::unique_ptr<object> p(new object);就足够了 你不必对它做任何事情,在它超出范围后它会摧毁它。

答案 2 :(得分:2)

是的,你正在以正确的方式使用它。但是,如果C ++ 14可用,您可以像这样创建它:

auto p = std::make_uniuqe<object>();

关于删除它。它不需要被删除。这是一般智能指针的想法。当它超出范围时,它将删除它自己分配的内存。

答案 3 :(得分:1)

  1. 是的,您没有以错误的方式使用unique_ptrunique_ptr使用资源获取初始化范例 - 即管理新对象是unique_ptr的责任。

  2. 这意味着您不必显式删除指针p,因为当unique_ptr超出范围(块的结尾或本例中的函数)时析构函数将设法以正确的方式释放内存而不会导致任何泄漏。

  3. 查看以下代码(与unique_ptr类似):

    template<class T>
    class ScopedPointer : NonCopiable{
    private:
        T * pointer;
    public:
         ScopedPointer( T  *p): pointer(p){};
    
        virtual ~ScopedPointer(){
    
                delete pointer;
        };
        T * operator->() const {return pointer;};
        T & operator*() const {return *pointer;};
    
    };
    

    ScopedPointer析构函数将负责删除原始指针!

答案 4 :(得分:0)

如果你可以使用C ++ 14,你可以有一个简短的手:

auto p = std::make_unique<object>();

这里没有内存泄漏,unique_ptr包装堆分配,当它超出范围时,它会释放资源。您不需要手动释放它,只需将其用作正常变量,当然要小心它。