2010-08-23 6 views
34

Я не уверен, что можно инициализировать shared_ptr, который является членом класса. Можете ли вы сказать мне, подходит ли то, что я выбираю в C::foo(), или есть лучшее решение?Как инициализировать shared_ptr, являющийся членом класса?

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); 
} 
+2

Используйте списки инициализации. – Chubsdad

+0

chubsdad: Не будет работать в членах, только в ctors. – MSalters

+0

@MSalters: Я понятия не имею, что вы пытаетесь сказать. – sbi

ответ

30

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

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

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

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

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

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

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

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


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

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

+1

Учитывая, что вы полагаетесь на это, стоит поговорить о том, как работает порядок построения членов и о точках последовательности. –

+0

@ereOn - Тип возврата для конструктора? – DumbCoder

+0

@DumbCoder: Скопирован из вопроса, где это также неправильно. Я починил это. – sbi