构造函数中创建、析构函数中删除的模式名称(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++类生存期,否则它变得丑陋,包括语言名称,我更愿意在这个答案中删除,因为语言是已知的)。
class A{B m_B={};}
就可以得到几乎相同的结果,但没有危险的指针,使用的代码少于1/4。您不需要使用private:
,因为class
关键字的整个要点是将成员private定义为默认值,因为它们应该位于类的顶部,而不是隐藏在底部的一个地方,你需要向下滚动整个页面才能看到它们。在我30年的编程生涯中,我从未见过一个参数将成员放在底部,而语言显然是要将它们放在顶部。由于编译器生成的复制构造函数,“拥有原始指针”应该扩展为“或任何其他类型的资源句柄”。这同样适用于文件句柄、套接字、数据库连接或任何其他必须管理其生命周期的资源。RAII:“资源获取就是初始化”@PabloArielcode显示的代码非常恶心
以什么方式?@PabloArielstd::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;
};