2012-03-03 40 views
2

有时,当一个对象用另一个对象的指针创建时,这意味着它负责销毁另一个对象,而不是其他对象。有时甚至有些情况可能因情况而异,而不是每个班级固定的规则。是否有描述哪个对象控制另一个对象的生命周期的模式?

很简单的例子:

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

我宁愿将它称为反模式。一个对象应该拥有另一个对象(必要时显式转移所有权),或者不拥有它(然后根本不删除它)。你的例子意味着类“A”的对象根据它们被初始化的方式表现不同,这对用户来说是令人惊讶的。 – Philipp 2012-03-03 18:04:22

+0

但是,传递NULL来表示一个类应该使用默认实现,IS通用。 – 2012-03-03 18:08:35

回答

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。

+0

智能指针不控制哪个对象负责另一个对象的销毁,但是 - 它只是在没有引用时允许_automatic_ deletion? – 2012-03-03 18:05:12

2

在理想情况下,你应该处理通过智能指针所有动态对象与自我描述语义(和周围的引用传递的访问,或像boost::optional可选引用)。

你举的例子可能是这样的:

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; } 
}; 
1

一个常见的模式是使用shared_ptr暗示共享所有权std::unique_ptr甚至中伤std::auto_ptr传达所有权转让的。

如果A的构造函数采用了shared_ptr<B>,那么A的析构函数将仅在没有更多共享指针的情况下删除该对象。

另一方面,A的构造函数采用auto_ptr<B>,则构造A的代码将不再能够访问B指针。所以很显然,A现在全权负责销毁。

在这两种情况下,所有权都由代码本身执行。

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将负责它的生命周期,如果一个空指针被传入。