38

我不确定初始化作为shared_ptr类成员的 a 的好方法。你能告诉我,我选择的方式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);
}
4

1 回答 1

30

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

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

这是更正确和安全的。

如果,无论出于何种原因,new Anew B抛出,你不会有泄漏。

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

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

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

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


我还建议您使用 ashared_ptr<A>而不是 aA*作为B构造函数的参数(如果它有意义并且您可以接受少量开销)。它可能会更安全。

也许可以保证一个实例B不能没有一个实例,A然后我的建议不适用,但是我们在这里缺乏上下文来给出一个明确的建议。

于 2010-08-23T07:22:38.080 回答