2012-04-23 12 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_; 
    } 

Uwaga: C jest parametrem szablonuCo to jest wyliczenie w destruktorze?

wiem, nie możemy usunąć pustego wskaźnika wyjątek zostanie podniesiona. Tak więc w tym przypadku definicja wyliczeniowa musi być czymś, aby temu zapobiec. W produkcji czasami nie chcemy zakończyć programu prostym, ponieważ mamy wskaźnik zerowy, możemy chcieć spojrzeć na alternatywny scenariusz, gdy wskaźnik jest pusty. A ten kod jest używany w produkcji, prawie wszędzie?

Dzięki chłopaki.

+7

Możemy usunąć wskaźnik zerowy, który jest do tego prawidłowy. –

+0

Myślę, że mój problem był mylony z podwójnym usunięciem wskaźników. Zawsze podnosi wyjątek, gdy kompilator wykryje podwójne usunięcie. Jaka jest więc różnica między usunięciem wskaźnika zerowego a podwójnym usunięciem? – maress

+2

@maress: możesz "usunąć" wskaźnik zerowy tyle razy ile chcesz (lub w rzeczywistości możesz spróbować go usunąć, środowisko wykonawcze wykryje wskaźnik zerowy i nie zrobi nic) – rjnilsson

Odpowiedz

17

to skutecznie statyczna asercja dla usunięcia. implementacja chce wiedzieć, czy ma do czynienia z typem, którego deklaracja jest widoczna przed usunięciem zmiennej, a nie z deklaracją forward.

Twój kompilator będzie emitować błąd, gdy pytasz to wielkość niekompletnego typu:

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

Aktualizacja

Jako kompilator i Matthieu M. powie - delete -ing typ niekompletny jest niezdefiniowany.

+1

Dlaczego nie używać 'sizeof (* ptr_)'? – sharptooth

+2

@sharptooth: Twierdzę, że 'C' jest bardziej przejrzysty, a także szybszy do wpisania :) –

+5

@Justin: warto byłoby wykluczyć, że próba" usunięcia "wskaźnika do niekompletnego typu jest ** niezdefiniowanym zachowaniem * *, dlatego warto ją zdiagnozować. Boost ma również "checked_delete" do tego samego efektu, mogliby go ponownie użyć, ale prawdopodobnie jest dość prosty, że nie myśleli, że uzasadnia to konkretny dodatek. –

0

Wzmocnienie checked_deleter wydaje się lepsze:

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

Ponieważ niektóre kompilator może powrócić 0, podczas gdy T jest Undefine, w tym przypadku

enum { type_must_be_complete = sizeof(T) }; 

jest poprawnym assert statyczne, ale checked_deleter będzie się niepowodzeniem.

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