我应该使用unique_ptr来保持班级成员吗?

LmT*_*oon 1 c++ pointers smart-pointers unique-ptr

我有这样的代码:

class A
{
public:
    A(void);
    ~A(void)
    {
        delete b;
        delete c;
        delete d;
        // ...
    }
private:
    B* b;
    C* c;
    D* d;
    // ...
};

//A.cpp
    A(void) : b(new B()), c(new C()), d(new D()) //...
    {  
    }
Run Code Online (Sandbox Code Playgroud)

A取得所有权在自己的对象b,c,d...什么是保持这些对象的最佳方式?我猜,std::unique_ptr<B/C/D>类型的使用将适合这种方式.例如,它允许不关心析构函数的仔细编写.

son*_*yao 6

它允许不关心析构函数的仔细编写.

比那更多的.

  1. 您的代码不是异常安全的.例如,如果new D()因抛出异常而失败,delete b并且delete c将不会执行并且内存将泄漏,因为如果构造函数失败则不会调用析构函数.智能指针可以帮助您避免这种情况.

  2. 将原始指针作为成员保存,您需要仔细实现析构函数,并复制构造函数和赋值等.看什么是三规则?三个规则成为C++ 11的五次规则?.


bob*_*bah 5

最好的方法是按价值保留一切。如果它适合*,并且不需要隐藏**。如果它不适合或需要隐藏,第一偏好是std::unique_ptr***,第二偏好(如果必须共享所有权)是std::shared_ptr。并且仅作为最后的手段(我什至想不出的例子)。您实际上将拥有原始指针并自己管理生命周期,但存在内存错误和泄漏的风险。

* - 有时您希望能够按值将父对象放在堆栈上,而子对象是大数组,如果按值存储会溢出堆栈

** - 有时你不想显示子对象到底是什么(因为它们很复杂,比如 boost.fusion 适应类。然后你会想要某种形式的 PIMPL 习语:

class.hpp
struct b;
struct A { std::unique_ptr<b> b_; A(); ~A(); }

class.cpp:
struct b { ... }
A::A() = default;
A::~A() = default;
Run Code Online (Sandbox Code Playgroud)

*** - 使用 unique_ptr 自动管理动态分配的成员

struct A {
  std::unique_ptr<b> b_;
  A(...):
    b_(std::make_unique<b>(...)) {}
};
Run Code Online (Sandbox Code Playgroud)