C++制作和销毁unique_ptr指针

C++ making and destroying unique_ptr pointer

本文关键字:unique ptr 指针 C++      更新时间:2023-10-16

我正在学习将指针与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) 指针,以便没有内存使用或泄漏?

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 d。

也就是说,在此示例中无需使用动态分配。您应该只使用自动变量:

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要么没有被创建,要么将被销毁并回收内存。

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

是的,你用对了。但是,如果 C++ 14 可用,您可以像这样创建它:

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

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

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

  2. 这意味着您不必显式删除指针p,因为当unique_ptr超出范围(块的末尾,或在这种情况下为函数)时,其析构函数将设法以正确的方式释放内存而不会造成任何泄漏。

查看以下代码(其工作原理与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析构函数将负责删除原始指针!

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

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

这里没有内存泄漏,unique_ptr包装堆分配,当它超出范围时,它会释放资源。你不需要手动释放它,只需将其用作普通变量,当然要注意它的范围。