如何初始化作为类成员的shared_ptr?

时间:2010-08-23 07:20:17

标签: c++ boost initialization shared-ptr member

我不确定初始化作为类成员的shared_ptr的好方法。你能告诉我,我在C::foo()中选择的方式是否合适,还是有更好的解决方案?

class A
{
  public:
    A();
};

class B
{
  public:
    B(A* pa);
};

class C
{
    boost::shared_ptr<A> mA;
    boost::shared_ptr<B> mB;
    void foo();
};

void C::foo() 
{
    A* pa = new A;
    mA = boost::shared_ptr<A>(pa);
    B* pB = new B(pa);
    mB = boost::shared_ptr<B>(pb);
}

1 个答案:

答案 0 :(得分:30)

您的代码非常正确(可行),但您可以使用初始化列表,如下所示:

C::C() :
  mA(new A),
  mB(new B(mA.get())
{
}

哪个更正确,更安全。

如果由于某种原因new Anew B抛出,您将无法泄露。

如果new A抛出,则不会分配任何内存,异常也会中止您的构造函数。什么都没有建成。

如果new B抛出,异常仍将中止您的构造函数:mA将被正确销毁。

当然,由于B的实例需要指向A实例的指针,因此成员的声明顺序很重要

成员声明顺序在您的示例中是正确的,但如果它被颠倒了,那么您的编译器可能会抱怨mBmA之前初始化mB并且可能会mA实例化失败(因为mA.get()尚未构造,因此调用shared_ptr<A>会调用未定义的行为。)


我还建议你使用A*而不是B作为B构造函数的参数(如果它会有感觉,如果你可以接受一点开销)。它可能会更安全。

也许保证A的实例不能在没有{{1}}的实例的情况下生存,然后我的建议不适用,但我们在这里缺乏上下文来提供明确的建议此