2017-05-12 46 views
5

Czy to dobra praktyka dla destruktorów override? Dlaczego lub dlaczego nie? przykład:Czy dobrą praktyką jest przesłonięcie destruktora?

class Foo : Base 
{ 
public: 
    ~Foo() override {} 
}; 
+0

O ile mogę powiedzieć, zduplikowane pytanie nie odpowiada, jeśli jest to dobra praktyka, w rzeczywistości istnieje bez odpowiedzi komentarz na ten temat. –

Odpowiedz

4
struct Base { 
    virtual ~Base() {} 
}; 
struct Foo : Base { 
    ~Foo() override {} 
}; 

ten zbiera.

struct Base { 
    ~Base() {} 
}; 
struct Foo : Base { 
    ~Foo() override {} 
}; 

tego nie robi.

struct Base { 
    ~Base() {} 
}; 
struct Foo : Base { 
    virtual ~Foo() {} 
}; 

To kompiluje.

Live example.

Jeśli twoim celem jest, aby stwierdzić, że w Foo można oczekiwać Base mieć virtual destruktora, najprostszym sposobem na to jest z override słowa kluczowego w ~Foo. Ponieważ semantyka usuwania znacznika Foo* zmienia się znacząco w zależności od tego, czy ~Foo jest , może to być przydatne dla niektórych osób.

Inne osoby mogą być obrażane, używając terminu override w celu odniesienia się do tej sytuacji.

Ustal, czy ludzie są offenced za pomocą override jest bardziej lub mniej ważne, niż jest w stanie stwierdzić, że w FooBase ma wirtualnego destruktora, więc usuwanie instancji Foo poprzez wskaźnik do Base definiuje zachowanie. Nie mogę podjąć tej decyzji za ciebie.

Jak zaznaczył @HowardHinnant w komentarzach, istnieją konsekwencje dla dodania wyraźnego destruktora; jeśli to zrobisz, postępuj zgodnie z zasadą 5 i albo =default, =delete lub zaimplementuj operatory konstruowania/przypisywania obiektów kopiowania/przenoszenia.

To może być łatwiejsze do static_assert, że Base ma wirtualny destruktor, chyba że potrzebujesz destruktora z jakiegoś innego powodu.

+4

Uzgodnione (i przegłosowane). Zastanów się jednak, czy najlepiej używać destruktora deklarowanego domyślnie. Po dodaniu destruktora ('override') niejawnie wyłącza się domyślnie deklarowanych członków ruchu. Jeśli członkowie Twojej kopii są niejawni, polegasz na nieaktualnym zachowaniu. To powinno być wzięte pod uwagę podczas dodawania destruktora deklarowanego przez użytkownika. Dodanie destruktora _only_ w celu oznaczenia go 'override' może być przesadą. Istnieją inne sposoby zapewnienia, że ​​'~ Foo()' jest 'wirtualne', np .:' static_assert (std :: has_virtual_destructor {}) '. –