Как инициализировать shared_ptr, который является членом class?

Я не уверен, как правильно инициализировать 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);
}
35
задан Igor Oks 23 August 2010 в 09:41
поделиться

1 ответ

Ваш код вполне правильный (он работает), но вы можете использовать список инициализации, например:

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

Что еще более правильно и безопасно.

Если по какой-либо причине выпадет новый A или новый B , утечки не будет.

Если new A выбрасывает, то память не выделяется, и исключение также прерывает работу вашего конструктора. Ничего не было построено.

Если new B выбрасывает, а исключение все равно прерывает ваш конструктор: mA будет уничтожен правильно.

Конечно, поскольку для экземпляра B требуется указатель на экземпляр A , порядок объявления членов имеет значение .

Порядок объявления элементов в вашем примере правильный, но если он был изменен на противоположный, то ваш компилятор, вероятно, пожаловался бы на инициализацию mB до mA и создание экземпляра mB , скорее всего, завершится ошибкой (поскольку mA еще не был создан, поэтому вызов mA.get () вызывает неопределенное поведение).


Я бы также посоветовал вам использовать shared_ptr вместо A * в качестве параметра для вашего конструктора B ( if он имеет смысл и если вы можете принять небольшие накладные расходы). Наверное, было бы безопаснее.

Возможно, гарантировано, что экземпляр B не может существовать без экземпляра A , и тогда мой совет неприменим, но нам здесь не хватает контекста, чтобы дать окончательный совет по этому поводу.

30
ответ дан 27 November 2019 в 15:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: