是否有描述哪个对象控制另一个生命周期的模式?

时间:2012-03-03 17:50:57

标签: c++ design-patterns

有时当使用指向另一个对象的指针创建一个对象时,这意味着它负责在销毁时销毁另一个对象......其他时候则不然。有时甚至有些情况会根据具体情况而有所不同,而不是每个班级的固定规则。

很简单的例子:

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()中你最终需要知道。当然你可以有一个小布尔标志,但我想知道这里是否有任何好用的模式?或者甚至可以将这种行为的名称放入代码注释中,以便其他开发人员能够获得更多线索?

4 个答案:

答案 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将负责其生命周期。