有时当使用指向另一个对象的指针创建一个对象时,这意味着它负责在销毁时销毁另一个对象......其他时候则不然。有时甚至有些情况会根据具体情况而有所不同,而不是每个班级的固定规则。
很简单的例子:
class A
{
private:
B *b;
public:
A(B *_b)
{
if(_b)b = _b; //A should NOT destroy b
else b = new B(); //A should destroy b
}
}
在A::~A()
中你最终需要知道。当然你可以有一个小布尔标志,但我想知道这里是否有任何好用的模式?或者甚至可以将这种行为的名称放入代码注释中,以便其他开发人员能够获得更多线索?
答案 0 :(得分:4)
一般的想法叫做“智能指针”,在你的具体例子中,你需要一个shared_ptr。
class A {
std::shared_ptr<B> b;
public:
A(std::shared_ptr<B> b = std::make_shared<B>())
: b(b) {}
};
请注意,如果编译器上没有std :: shared_ptr,则必须使用boost :: shared_ptr。
答案 1 :(得分:2)
在理想情况下,您应该通过具有自描述语义的智能指针处理所有动态对象(并传递引用以进行访问,或类似boost::optional
的可选引用)。 / p>
您的示例可能如下所示:
class A
{
std::unique_ptr<B> bptr;
public:
A(std::unique_ptr<B> && b) : bptr(b ? b : new B) { }
B & b() { return *bptr; }
B const & b() const { return *bptr; }
};
答案 2 :(得分:1)
一种常见的模式是使用shared_ptr
来暗示共享所有权和std::unique_ptr
甚至是受到诽谤的std::auto_ptr
来传达所有权转移强>
如果A
的构造函数采用shared_ptr<B>
,则A
的析构函数将仅在没有更多共享指针的情况下删除该对象。
另一方面,A
的构造函数使用auto_ptr<B>
,然后构造A
的代码将无法再访问B
指针。所以很明显A
现在只对它的毁灭负责。
在这两种情况下,所有权都由代码本身强制执行。
答案 3 :(得分:1)
你可以用两个指针处理这个问题,一个聪明,一个愚蠢:
class A
{
private:
B *b;
std::unique_ptr<B> ub;
public:
A(B *_b)
{
if(_b)
b = _b;
else
{
ub.reset(new B);
b = ub.get();
}
}
};
在类中,您将通过哑指针处理对象,但如果传入空指针,unique_ptr将负责其生命周期。