Per quanto riguarda i puntatori che sono membri delle classi. Dovrebbero essere di tipo puntatore intelligente o è sufficiente gestirli semplicemente con il distruttore della classe in cui sono contenuti?
Per quanto riguarda i puntatori che sono membri delle classi. Dovrebbero essere di tipo puntatore intelligente o è sufficiente gestirli semplicemente con il distruttore della classe in cui sono contenuti?
No, non è sufficiente gestire il puntatore raw nel distruttore. Inoltre, devi occupartene nelle funzioni di costruzione copia e assegnazione operatore. Di solito non è sufficiente copiare semplicemente il puntatore (che il compilatore farà felicemente per te); probabilmente vuoi veramente fare una copia della risorsa a cui punta. E devi ricordare di gestire con grazia l'autoassegnazione senza far trapelare la risorsa. Forse non vuoi affatto supportare la copia, quindi devi ricordarti di disabilitare esplicitamente queste funzioni. Forse vuoi dare maniglie a quella risorsa, quindi devi tenere traccia di quando è sicuro essere liberati. Cosa succede se un'eccezione viene lanciata nel mezzo del tuo costruttore? E se tu non fossi tu a lanciarlo? Forse c'è un altro caso limite a cui non ho pensato.
(Nota: ho eseguito il debug più che sufficiente di questo tipo di codice che si sbaglia, quindi il mio tono un po 'aspro.)
Se vuoi farlo bene al primo tentativo, allora sì, dovresti usare un tipo di puntatore intelligente come boost::scoped_ptr
o std::tr1::shared_ptr
.
Beh, se sono solo membri, preferisco non occuparmi di eliminare e utilizzare boost :: scoped_ptr. Per me questo è il modo più semplice per gestirlo.
Ora, se non hai accesso a boost, o non vuoi usarlo, puoi creare un semplice puntatore intelligente che ti fa semplicemente cancellare nel distruttore. È davvero facile e ti lascio fare come esercizio, se ne hai bisogno.
Alla fine, solo se sono "obbligato" a usare delete nel distruttore della classe owner. Il problema è che so che cambierà in futuro e se aspettiamo abbastanza, cambierà in un modo che renderà l'eliminazione errata. Quando ciò accade, nessuno ricorderà che c'è stata una cancellazione, fino a quando non si blocca ...
Quindi, è meglio impostare la regola di distruzione nel punto di creazione o definizione invece di un'altra nella base di codice (da qualche parte nessuno si ricorderà perché è lontana dal punto di definizione).
Ecco perché utilizziamo puntatori intelligenti dove possibile.
Come sempre, non è una buona idea usare puntatori intelligenti per tutto, ma in questo caso specifico, se il tuo membro viene creato solo con la costruzione del proprietario e distrutto con la distruzione del proprietario, rendi la vita facile, usa un puntatore intelligente.
Leggi altre domande sui tag c++ class memory pointers smart-pointer