2010-08-23 12 views
34

Non sono sicuro di un buon modo per inizializzare uno shared_ptr membro di una classe. Puoi dirmi se il modo in cui scelgo lo C::foo() va bene o esiste una soluzione migliore?Come inizializzare un shared_ptr che è un membro di una classe?

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

Utilizzare gli elenchi di inizializzazione. – Chubsdad

+0

chubsdad: Non funziona nei membri, solo nei medici. – MSalters

+0

@MSalters: non ho idea di cosa stai cercando di dire. – sbi

risposta

30

Il codice è del tutto corretto (funziona), ma è possibile utilizzare l'elenco di inizializzazione, in questo modo:

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

che è ancora più corretto e come sicuro.

Se, per qualsiasi motivo, new A o new B genera, non avrai perdite.

Se new A genera, non viene allocata alcuna memoria e l'eccezione interrompe anche il costruttore. Niente è stato costruito

Se new B genera e l'eccezione interromperà ancora il costruttore: mA verrà distrutto correttamente.

Naturalmente, dal momento che un'istanza di B richiede un puntatore a un'istanza di A, l'ordine di dichiarazione dei membri conta.

L'ordine di dichiarazione parlamentare ha ragione nel tuo esempio, ma se è stato invertito, quindi il compilatore sarebbe probabilmente lamentarsi mB beeing inizializzati prima mA e l'istanza di mB sarebbe probabilmente fallire (dal mA non sarebbero stati ancora costruiti, in tal modo chiamare mA.get() richiama il comportamento non definito).


Vorrei anche suggerire di utilizzare un shared_ptr<A> invece di un A* come parametro per il costruttore di B (se Rende sensi e se si può accettare la piccola testa). Probabilmente sarebbe più sicuro.

Forse è garantito che un'istanza di B non possa vivere senza un'istanza di A e quindi il mio consiglio non si applica, ma qui manca il contesto per dare un consiglio definitivo in merito.

+1

Dato che ci si basa su di esso, vale la pena parlare del modo in cui l'ordine di costruzione dei membri funziona e dei punti di sequenza coinvolti. –

+0

@ereOn - Un tipo di ritorno per un costruttore? – DumbCoder

+0

@DumbCoder: copiato dalla domanda in cui è anche sbagliato. L'ho riparato. – sbi

Problemi correlati