shared_ptr作为类成员

9

在头文件中“前向声明”该类的指针作为其包含对象是很常见的做法,这样可以降低代码的物理依赖性。

例如:

class B;  // forward declaration   

class A {
   private:
      B* pB;
};

声明这样的成员为shared_ptr,而不是裸指针,会是一个好主意吗?

我更喜欢scoped_ptr,但据我所知,它不会成为标准。


如果您需要共享指针语义,为什么不呢?实际上,我并不清楚您在询问什么。 - anon
我不需要共享指针语义。由于我将B声明为指向B的指针(以减少类A之间的物理依赖关系),因此我需要调用new来创建B。因此,我需要在A的d-tor中删除它。这并不是太麻烦,但问题是在这里使用shared_ptr来处理B的释放是否是一个好的实践。 - dimba
如果你不需要共享指针所提供的功能,为什么要使用它?如果你不需要指针所提供的功能,也不要使用它。一个相当好的经验法则是不要使用与你正在尝试做的事情不匹配的语言特性。 - jalf
shared_ptr / unique_ptr 万岁!! - AndersK
为什么它可以减少代码中的物理依赖关系。 - Alston
4个回答

7

是的,你可以(应该?)这样做。

这是一种常见的做法。正如你所说,它避免了需要显式调用delete()的需求。

你甚至可以更进一步。这里有一个例子:

class RSAKey
{
  public:

    RSAKey();

  private:

    shared_ptr<RSA> d_rsa; // A pointer to a RSA structure from OpenSSL
}

我会这样初始化:

RSAKey::RSAKey()
{
  RSA* rsa = RSA_generate_key(1024, 1, NULL, NULL);

  if (NULL == rsa) throw DummyException();

  d_rsa.reset(rsa, RSA_free); // Note the specific release method.
}

当不再使用d_rsa时,将自动调用RSA_free()。这不是很酷吗?!
更新
如果可以选择C++11,最好使用std::unique_ptr代替,它的开销较小且可移动。
这取决于您希望封装类在复制方面的行为方式。

自动成员释放正是我的问题 :) - dimba

2

如果这个指针不会传递出你的类实现,而且执行速度很重要,那么使用scoped_ptr而不是shared_ptr。shared_ptr有额外的开销。


我相信scoped_ptr不在即将到来的C++0X标准中。 - dimba
3
@idimba,unique_ptr是C++版本的智能指针,它也支持移动语义。 - Johannes Schaub - litb

1

使用 shared_ptr 可以让您将所有权传递给另一个对象,这样当您的外部对象被销毁时,它不会被销毁。您表示在这种情况下这不会成为一个问题。

智能指针唯一的好处就是您无需记得在析构函数中放置 delete pB。对于大多数人来说,这可能已经足够优点了。

当您不需要担心所有权问题时,即使是 auto_ptr 也足够好。


0

如果涉及到组合,如果您不想要物理依赖,那么这是一个好主意。这样当A被销毁时,B也会自动被销毁。

如果您不介意物理依赖,可以直接按值持有数据成员。

(如果物理依赖是一个问题,您还可以检查pimpl习惯用法。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接