【问题标题】:Pattern name for create in constructor, delete in destructor (C++)在构造函数中创建模式名称,在析构函数中删除 (C++)
【发布时间】:2010-12-23 04:49:02
【问题描述】:

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

class A
{
 public:
    A() { m_b = new B(); }
    ~A() { delete m_b; }
 private:
    B* m_b;
};

这种资源获取技术/模式,有没有通用的名字?
我很确定我在某处读过它,但现在找不到。

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

【问题讨论】:

  • Bad class A. 缺少复制构造函数和赋值运算符。
  • 如果不需要复制/分配,一个更简单的解决方案是从 boost::noncopyable 派生。无需定义这两个函数。 (并确保它们不会被意外调用)
  • 对动态内存的使用毫无意义。这门课的设计和格式真是太糟糕了。总体而言,这是一个多么糟糕的 C++ 示例。你为什么要那样做?无论如何,您为什么会以如此毫无意义的方式使用 new 和 delete 。只需执行class A{ B m_b = {}; },您就会得到几乎相同的结果,但没有危险的指针,并且使用的代码不到 1/4。
  • 您不需要使用private:,因为class 关键字的全部意义是将成员定义为默认值,因为它们应该位于类的顶部,并且没有隐藏在底部的地方,您需要向下滚动整个页面才能看到它们。在我 30 年的编程生涯中,我从未见过将成员置于底层的单一论点,而该语言显然意味着将它们置于顶层。

标签: c++ design-patterns raii


【解决方案1】:

RAII - 资源获取正在初始化

【讨论】:

  • 虽然通常您会使用智能指针为您执行 RAII,而不是自己编写代码
  • 不一定。自己编写 RAII 类可以让您更好地控制资源的生命周期管理。智能指针只是 RAII 的众多可能示例之一。成语涵盖的多于boost::shared_ptr
【解决方案2】:

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

但是你的例子很危险:

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

class A
{
  public:
     A(): m_b(new B) {}
  private:
     boost::shared_ptr<B> m_b;
};

解决方案 2:记住规则 4:
如果您的类包含“Owned 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;
};

我使用上面的术语“Owned RAW Pointer”,因为它是最简单的例子。但是 RAII 适用于所有资源,并且当您的对象包含您需要管理的资源('Owned RAW Poiner'、DB Handle 等)时。

【讨论】:

  • 因为编译器生成了拷贝构造函数。
  • “拥有一个原始指针”可能应该扩展为“或任何其他类型的资源句柄”。这同样适用于文件句柄、套接字、数据库连接或必须管理其生命周期的任何其他资源。
  • RAII:“资源采集正在初始化”
  • @PabloAriel code shown is quite disgusting以什么方式?
  • @PabloAriel std::vector&lt;&gt; 我敢打赌它的构造函数中有一个新的:-)。基本上任何时候你创建一个容器或一个智能指针,这些都是必要的。仅仅因为标准库有最常见的库并不意味着你永远不会遇到标准库不够用的情况(所以你应该知道在需要时如何去做)。虽然不可否认,这些将非常罕见。每个人都应该尝试创建一个容器/智能指针(不仅是为了学习经验,也是为了了解他们做正确的难度)。
【解决方案3】:

这种技术最为人所知的是RAII - 资源分配是初始化。它在这个网站上有自己的tag

另类。建议使用更直观的名称,尤其是:

【讨论】:

    猜你喜欢
    • 2018-04-30
    • 2021-04-12
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多