在构造函数中创建的模式名称,在析构函数中删除(C++)

Zen*_*Zen 10 c++ design-patterns raii

传统上,在C++中,您将在构造函数中创建任何依赖项,并在析构函数中删除它们.

class A
{
 public:
    A() { m_b = new B(); }
    ~A() { delete m_b; }
 private:
    B* m_b;
};
Run Code Online (Sandbox Code Playgroud)

这种技术/资源获取模式,它有一个共同的名称吗?
我很确定我已经在某处读过它但现在找不到它.

编辑:
正如许多人所指出的,这个类是不完整的,应该真正实现一个复制构造函数和赋值运算符.
最初,我故意将其遗漏,因为它与实际问题无关:模式的名称.但是,为了完整性和鼓励良好实践,接受的答案就是它.

Jon*_*ler 19

RAII - 资源获取是初始化

  • 不必要.自己编写RAII类可以更好地控制资源的生命周期管理.智能指针只是RAII的许多可能示例之一.成语涵盖*远*超过`boost :: shared_ptr` (4认同)

Mar*_*ork 14

您的问题的答案是RAII(资源获取是初始化).

但你的例子是危险的:

解决方案1使用智能指针:

class A
{
  public:
     A(): m_b(new B) {}
  private:
     boost::shared_ptr<B> m_b;
};
Run Code Online (Sandbox Code Playgroud)

解决方案2:记住规则4:
如果您的类包含"拥有RAW指针",那么您需要覆盖所有编译器生成的方法.

class A
{
  public:
     A():              m_b(new B)           {}
     A(A const& copy): m_b(new B(copy.m_b)) {}
     A& operator=(A const& copy)
     {
         A  tmp(copy);
         swap(tmp);
         return *this;
     }
    ~A()
     {
         delete m_b;
     }
     void swap(A& dst) throw ()
     {
         using std::swap;
         swap(m_b, dst.m_b);
     }
  private:
     B* m_b;
};
Run Code Online (Sandbox Code Playgroud)

我使用上面的"拥有RAW指针"一词,因为它是最简单的例子.但是RAII适用于所有资源,并且当您的对象包含您需要管理的资源时("拥有RAW Poiner","DB Handle"等).

  • 因为编译器生成了复制构造函数. (5认同)
  • "拥有一个原始指针"应该扩展为"或任何其他类型的资源句柄".这同样适用于文件句柄,套接字,数据库连接或其生命周期必须被管理的任何其他资源. (2认同)