standardmäßig überschreiben von virtuellen Destruktor

Jeder weiß, dass die desructor der Basis-Klasse in der Regel werden virtuelle. Aber was ist über den Destruktor der abgeleiteten Klasse? In C++11 wir haben das Schlüsselwort "override" und die Fähigkeit zur Nutzung der Standard-Destruktor explizit.

struct Parent
{
  std::string a;
  virtual ~Parent()
  {
  }

};

struct Child: public Parent
{
  std::string b;
  ~Child() override = default;
};

Ist es nicht richtig zu verwenden Sie die beiden Schlüsselwörter "override" und "=default" im Destruktor der abgeleiteten Klasse? Werden compiler generieren, die richtigen virtuellen Destruktor in diesem Fall?

Wenn ja, dann können wir denken, dass es ist guter Programmierstil, und wir sollten uns immer deklarieren Sie Destruktoren von abgeleiteten Klassen diese Möglichkeit, um sicherzustellen, dass die base class Destruktoren virtuell sind?

  • Könnten das auch tun static_assert(std::has_virtual_destructor<Parent>::value, "contract violated");
  • Beachten Sie, dass es nicht immer eine Voraussetzung, dass die Basis-Klasse Destruktor virtuell sein. Das ist also nur (eventuell) eine gute Idee, wenn das ist eine Voraussetzung.
  • Wenn es funktioniert, wie ich es mag, aber milleniumbug ist besser (viel deutlicher Absicht). Auf der anderen Seite, Stroustrup hasst "coding standard" - Konstrukte, die Wache gegen gemeinsame Fehler, und beharrt darauf, dass der compiler generieren soll geeignete Warnungen, statt.
  • Ich denke, @milleniumbug Ansatz drückt die Absicht klar. Wenn stieß ich auf ~Child() override = default; in einer code-Basis könnte ich einfach die Zeile entfernen.
  • Gut, mit static_assert erfordert die gleiche Menge an Programmierer Disziplin als mit virtuellen Destruktor, also bin ich nicht sicher, wie man besser ist als andere.
  • Ich bin verwirrt. Der Punkt, der override--die nur point--ist, Sie zu zwingen, zu einem compiler-Fehler, wenn die Eltern die Methode nicht virtual. Wie ist ein static_assert eine Verbesserung?
  • Es hängt davon ab, wie Sie es verwenden. Es ist eine Anforderung, die in einigen Fällen (wenn Sie arbeiten mit Zeigern auf Basisklasse).
  • Nur, wenn Sie Sie löschen, sagte Zeiger. Jedenfalls denke ich, dass ich falsch verstanden, das Ende Ihrer Frage.
  • Die static_assert werden könnte, gelegt in eine cpp-Datei, die macht es bequemer, um es hinzuzufügen, ohne dass eine Neukompilierung - und auch ausblenden, es als eine Implementierung detail. Doch, das würde es schwieriger machen, zu finden - und der Nachteil mit static_assert ist, dass Sie müssen wiederholen Sie den name der Basis-Klasse; in der Erwägung, überschreiben Sie nur die minimal benötigten Informationen.
  • Lieber die static_assert scheint wie Wahnsinn. Wenn stieß ich auf den static_assert version, ich würde es ersetzen mit override; das ist der Punkt, der override, in der Erwägung, dass static_assert ist nur verwirrend und nicht-idiomatische Weg, um zu versuchen zu schreiben, in verbose Schutz gegen Schießen selbst in den Fuß. Jede Zeile code ist eine Haftung, insbesondere nicht-idiomatische und verwirrend lieben.
  • IYAM, wenn man mit jemandem zufällig zu entfernen virtualness der Destruktor in Ihre base-Klasse, Sie haben größere Probleme zu bewältigen (siehe "Vertrag verletzt" - Meldung). Und wenn eine third-party Bibliothek ist dabei, dass, oh boy.
  • Richtig, beide Konstrukte sind nur Möglichkeiten, verursachen Fehler bei der Kompilierung, wenn etwas passiert, dass wirklich wirklich wirklich sollte nicht passieren. Aber das hat auch nicht wirklich erklären, warum die weniger idiomatischen ein, die anhand komplizierter Typ-trait-Reflexion, ist vorzuziehen.
  • die static_assert sagt Ihnen genau, was erforderlich ist, und ist vollkommen idiomatisch. Wenn static_assert führt zu Verwirrung, kann es sich lohnen sich etwas Zeit nehmen, um zu studieren, etwas C++. Die andere option sieht mir zu sehr nach redundanten code.
  • "es kann sich lohnen, nehmen Sie sich etwas Zeit und studieren einige C++" - finden Sie in "die Schuld der Programmierer" am Ende des diesem post. Beachten Sie auch, dass ich nicht wirklich sagen, dass ich nicht verstehe, die static_assert nur, dass es mehr verwirrend als die override version. Das ist wahr, denn es ist länger, Ausführlicher, und verwendet eine vergleichsweise obskure Funktion der standard-Bibliothek.
  • Der Punkt ist, dass die Prüfung für virtualness der Basis-Destruktor ist nicht die Verantwortung der abgeleiteten Klasse. Es ist eine Verantwortung für diejenigen, die wirklich ein base-Pointer auf abgeleitete Klassen von Objekten und Aufruf delete auf Sie.
  • Zu aufwändig: wenn Sie über 30 abgeleitete Klassen, werden Sie versehen alle von Ihnen? Nein? Gut. (Seite Bemerkung: std::unique_ptr ist ein ausgezeichneter Ort, um dies zu überprüfen, aber ich glaube nicht, dass ein solcher check erforderlich ist standard)
  • Ich Stimme nicht aus einer design-Perspektive. Klassen sollten so ausgelegt sein, dass Sie deleted sicher von a Cursor an eine beliebige Stelle in der Hierarchie der Klasse; überprüfung, ob die Klasse war richtig, in dieser Art gestaltet ist, sollte nicht die Sorge des Programmierers, da sollten wir erwarten, dass der Unterricht gut gestaltet. (Dies ist der Punkt, von Klassen-zu unterteilen, das problem des Raumes in der diskreten design-Probleme).
  • Ich bin allerdings der Meinung, dass der compiler sollte eine Warnung ausgeben, wenn ein base class pointer ist aus einer abgeleiteten Klasse die Basisklasse destructor ist nicht virtual, denn dies ist der erste Schritt in die falsche delete situation. Ich kenne leider kein compiler tatsächlich implementiert diese option Warnung.
  • Und, wieder, dein Einwand über Anmerkungen 30 abgeleiteten Klassen gilt für beide Konstrukte (override und static_assert) gleich gut, und nicht alle zeigen, dass man der anderen vorgezogen (obwohl es sicherlich ein argument gegen so eine Anmerkung als eine Regel-of-Daumen ist wie die Frage fragt).
  • "Jeder weiß, dass die desructor der Basis-Klasse in der Regel werden virtuelle." Ehm Nein nicht wirklich
  • Sind Sie auf den Einwand "jeder weiß" oder "in der Regel werden virtuelle"? (Oder beide?)
  • Die letzteren, etwa als eine Folge der ersteren.
  • Ich bin nicht sicher, wie ein static_assert, dass explizit verlangt die Basisklasse einen virtuellen Destruktor ist eher verwirrend als das deklarieren einen Destruktor in der Klasse, wenn Sie gar nicht benötigen, nur so können Sie die gleiche Sache. Und es dauert etwa drei Sekunden, um zu erklären, die static_assert zu jeder kompetente Programmierer, der findet, dass festure verschleiern in keiner Weise.

InformationsquelleAutor Sandro | 2016-12-06
Schreibe einen Kommentar