2012-04-23 7 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 es un parámetro de plantilla¿Para qué es esta enumeración en el destructor?

Sé que no podemos borrar un puntero nulo, se produce una excepción. Entonces, en este caso, la definición enum debe estar haciendo algo para evitar eso. En producción, a veces no queremos finalizar un programa simple porque tenemos un puntero nulo, es posible que deseemos ver un escenario alternativo, cuando el puntero es nulo. Y este código se usa en producción, casi en todas partes?

Gracias chicos.

+7

Podemos eliminar un puntero nulo es perfectamente válida para hacerlo. –

+0

Creo que mi problema se confunde con la eliminación doble de punteros. Siempre genera una excepción cuando el compilador detecta una eliminación doble. Entonces, ¿cuál es la diferencia entre eliminar un puntero nulo y una eliminación doble? – maress

+2

@maress: puede "eliminar" un puntero nulo tantas veces como quiera (o en realidad, puede intentar eliminarlo, el tiempo de ejecución detectará el puntero nulo y no hará nada) – rjnilsson

Respuesta

17

es efectivamente una afirmación estática para la eliminación. la implementación quiere saber si se trata de un tipo cuya declaración es visible antes de eliminar la variable, en lugar de una declaración directa.

su compilador emitirá un error cuando se pide que el tamaño de un tipo incompleto:

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

actualización

medida que su compilador y Matthieu M. le dirá - delete -ing un tipo incompleto no está definido.

+1

¿Por qué no usar 'sizeof (* ptr_)'? – sharptooth

+2

@sharptooth: Yo diría que 'C' es más clara, y es más rápido escribir también :) –

+5

@Justin: valdría la pena precisar que intentar 'borrar' un puntero a un tipo incompleto es ** comportamiento indefinido * *, por lo que vale la pena diagnosticarlo. Boost también tiene 'checked_delete' con el mismo efecto, podrían haberlo reutilizado, pero probablemente sea lo suficientemente simple como para pensar que no justificaba una inclusión específica. –

0

El impulso checked_deleter parece mejor:

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

Debido a que algunos compilador puede devolver 0, mientras que T es undefine, en ese caso

enum { type_must_be_complete = sizeof(T) }; 

es una aserción estática válida, pero no se checked_deleter.

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