C++ Antipattern?
-
Was haltet ihr von sowas?
class Foo{ virtual void x(){}; }; class Bar{ }; template<class T> class Helper : public Foo, public T{ }; void call(Foo* foo) { if(dynamic_cast<Bar*>(foo) != NULL) { std::cout<<"bar"; } } int main(int argc, char** argv) { Helper<Bar> h; call(&h); return 0; }
-
Hat die Frage auch noch nen Inhalt?
Abgesehen davon: klar, Antipattern pur. Außerdem müssen Foo und Bar virtuelle Destruktoren erhalten.
-
Konrad Rudolph schrieb:
Hat die Frage auch noch nen Inhalt?
Abgesehen davon: klar, Antipattern pur. Außerdem müssen Foo und Bar virtuelle Destruktoren erhalten.
Warum müssen? Ich sehe keinen Grund. Ein virtueller Destruktor ist nur dann notwendig, wenn ich die Klasse über einen Zeiger auf die Basisklasse lösche. In dem Fall wäre der Destruktor der abgeleiteten Klasse nicht erreichbar, wenn er nicht virtuell wäre. In dem Beispiel ist das aber kein Problem.
-
tntnet schrieb:
Konrad Rudolph schrieb:
Hat die Frage auch noch nen Inhalt?
Abgesehen davon: klar, Antipattern pur. Außerdem müssen Foo und Bar virtuelle Destruktoren erhalten.
Warum müssen? Ich sehe keinen Grund. Ein virtueller Destruktor ist nur dann notwendig, wenn ich die Klasse über einen Zeiger auf die Basisklasse lösche.
Eben. Und wer sagt denn, dass das nicht (in Zukunft) irgendwann passiert?
Die Regel ist doch ganz einfach: sobald ich einen Zeiger auf die Basisklasse erstelle, besteht die Gefahr, dass ich diesen entsorgt. Oder noch einfacher: Wenn eine Klasse als Basisklasse einer anderen Klasse agieren soll, dann braucht sie einen virtuellen Destruktor.
Unter beschränkenden Annahmen (z.B. wenn ich sicher bin, dass ich nie einen Zeiger manuell per 'delete' lösche) gilt diese Regel zwar nicht mehr, aber sie ist trotzdem eine gute Faustregel. Wenn mir jemand ein allgemeines Stück Code wie das obige zeigt, ohne dass er durch dokumentierende Kommentare ausdrücklich darauf hinweist, dass diese Klasse *nicht* wie oben erwähnt eingesetzt werden kann, dann braucht sie einen virtuellen Destruktor, alles andere kommt einer Garantie für Desaster gleich.
-
Destruktoren von Klassen, die als Basis Klasse dienen:
Entweder:
- public virtual (auf der Basis Klasse wird delete aufgerufen)
oder
- protected non- virtual (auf der Basis Klasse kann kein delete aufgerufen werden).Gruss SImon