Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
构造函数中创建、析构函数中删除的模式名称(C+;+;) 传统上,在C++中,您将在构造函数中创建任何依赖项,并在析构函数中删除它们。 class A { public: A() { m_b = new B(); } ~A() { delete m_b; } private: B* m_b; };_C++_Design Patterns_Raii - Fatal编程技术网

构造函数中创建、析构函数中删除的模式名称(C+;+;) 传统上,在C++中,您将在构造函数中创建任何依赖项,并在析构函数中删除它们。 class A { public: A() { m_b = new B(); } ~A() { delete m_b; } private: B* m_b; };

构造函数中创建、析构函数中删除的模式名称(C+;+;) 传统上,在C++中,您将在构造函数中创建任何依赖项,并在析构函数中删除它们。 class A { public: A() { m_b = new B(); } ~A() { delete m_b; } private: B* m_b; };,c++,design-patterns,raii,C++,Design Patterns,Raii,这种获取资源的技术/模式,有共同的名称吗? 我很肯定我在什么地方读过,但现在找不到 编辑: 正如许多人指出的,这个类是不完整的,应该真正实现一个复制构造函数和赋值运算符。 最初,我故意将其忽略,因为它与实际问题无关:模式的名称。但是,为了完整性和鼓励良好实践,公认的答案是正确的。资源获取是初始化。您的问题的答案是RAII(资源获取是初始化) 但你的例子很危险: 解决方案1使用智能指针: class A { public: A(): m_b(new B) {} private:

这种获取资源的技术/模式,有共同的名称吗?
我很肯定我在什么地方读过,但现在找不到

编辑:
正如许多人指出的,这个类是不完整的,应该真正实现一个复制构造函数和赋值运算符。

最初,我故意将其忽略,因为它与实际问题无关:模式的名称。但是,为了完整性和鼓励良好实践,公认的答案是正确的。

资源获取是初始化。

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

但你的例子很危险:

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

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

我使用上面的术语“拥有的原始指针”,因为它是最简单的示例。但是RAII适用于所有资源,并且当您的对象包含您需要管理的资源时(“拥有的原始Poiner”、DB句柄等)。

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

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

  • (原始建议,<强> LeCyoEeGu-生命等于C++类生存期,否则它变得丑陋,包括语言名称,我更愿意在这个答案中删除,因为语言是已知的)。
虽然通常情况下,您会使用智能指针为自己编写RAII,而不是自己编写代码,但不一定如此。自己编写RAII类可以更好地控制资源的生命周期管理。智能指针只是RAII的许多可能示例之一。这个习惯用法所涵盖的远远不止是坏的A类。缺少复制构造函数和赋值运算符。如果不需要复制/赋值,一个更简单的解决方案是从boost::noncopyable派生。省去了定义这两个函数的麻烦。(并确保它们不会被意外调用)动态内存的无意义使用。这个类的设计和格式真糟糕。C++的一个可怕的例子。你为什么要这么做?你为什么要使用new和delete,而且这样做毫无意义。只要执行
class A{B m_B={};}
就可以得到几乎相同的结果,但没有危险的指针,使用的代码少于1/4。您不需要使用
private:
,因为
class
关键字的整个要点是将成员private定义为默认值,因为它们应该位于类的顶部,而不是隐藏在底部的一个地方,你需要向下滚动整个页面才能看到它们。在我30年的编程生涯中,我从未见过一个参数将成员放在底部,而语言显然是要将它们放在顶部。由于编译器生成的复制构造函数,“拥有原始指针”应该扩展为“或任何其他类型的资源句柄”。这同样适用于文件句柄、套接字、数据库连接或任何其他必须管理其生命周期的资源。RAII:“资源获取就是初始化”@PabloAriel
code显示的代码非常恶心
以什么方式?@PabloAriel
std::vector
我打赌它的构造函数中有一个新的:-)。基本上,无论何时创建容器或智能指针,这些都是必需的。仅仅因为标准库有最常见的库,并不意味着您永远不会遇到标准库不足的情况(因此您应该知道在需要时如何做到)。尽管无可否认,这将是非常罕见的。每个人都应该尝试创建一个容器/智能指针(不仅是为了学习经验,也是为了了解正确操作有多困难)。
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;
};