2012-04-23 14 views
14
// Destructor. If there is a C object, delete it. 
// We don't need to test ptr_ == NULL because C++ does that for us 

    ~scoped_ptr() { 
     enum { type_must_be_complete = sizeof(C) }; 
     delete ptr_; 
    } 

Nota: C è un parametro di templateCos'è questo enum nel distruttore?

So che non possiamo eliminare un puntatore nullo, un'eccezione sarà sollevata. Quindi, in questo caso, la definizione enum deve fare qualcosa per impedirlo. In produzione, a volte non vogliamo terminare un programma semplice perché abbiamo un puntatore nullo, potremmo voler guardare uno scenario alternativo, quando il puntatore è nullo. E questo codice è utilizzato in produzione, quasi ovunque?

Grazie ragazzi.

+7

Siamo in grado di eliminare un puntatore nullo è perfettamente valido per farlo. –

+0

Penso che il mio problema sia stato confuso con la doppia eliminazione dei puntatori. Solleva sempre un'eccezione quando viene rilevata una doppia cancellazione dal compilatore. Quindi qual è la differenza tra l'eliminazione di un puntatore nullo e la doppia eliminazione? – maress

+2

@maress: puoi "cancellare" un puntatore nullo tutte le volte che vuoi (o in realtà, puoi provare ad eliminarlo, il runtime rileverà il puntatore nullo e non fare nulla) – rjnilsson

risposta

17

è in pratica un'asserzione statica per la cancellazione. l'implementazione vuole sapere se si tratta di un tipo la cui dichiarazione è visibile prima di eliminare la variabile, piuttosto che una dichiarazione in avanti.

il compilatore emetterà un errore quando si chiede che la dimensione di un tipo incompleto:

struct S; 
enum { Size = sizeof(S) }; 

Aggiornamento

Come il vostro compilatore e Matthieu M. vi dirà - delete -ing un tipo incompleto non è definito.

+1

Perché non usare 'sizeof (* ptr_)'? – sharptooth

+2

@sharptooth: direi che 'C' è più chiaro, ed è anche più veloce da scrivere :) –

+5

@Justin: varrebbe la pena precedere che il tentativo di eliminare un puntatore su un tipo incompleto è ** comportamento indefinito * *, ecco perché vale la pena diagnosticare. Boost ha anche 'checked_delete' per lo stesso effetto, potrebbero averlo riutilizzato ma è probabilmente abbastanza semplice che non pensavano che garantisse una specifica inclusione. –

0

Il checked_deleter spinta sembra migliore:

template<class T> struct checked_deleter 
{ 
    typedef void result_type; 
    typedef T * argument_type; 
    void operator()(T * p) const; 
}; 

Poiché alcuni compilatore può restituire 0 mentre T è undefine, in questo caso

enum { type_must_be_complete = sizeof(T) }; 

è un'assert statica valida, ma checked_deleter sarà fallito.

http://www.boost.org/doc/libs/1_59_0/libs/core/doc/html/core/checked_delete.html#core.checked_delete.checked_deleter