22 Stimmen

Privat oder öffentlich von boost::non_copyable erben?

Welche Praxis würden Sie empfehlen und warum?

class Foo : public boost::noncopyable {};

vs.

class Foo : private boost::noncopyable {};

Ich kann mir nicht vorstellen, dass ich eine Instanz von Foo als boost::noncopyable verwenden muss, daher tendiere ich in diesem Fall zur privaten Vererbung.

26voto

Nikolai Fetissov Punkte 79627

boost::noncopyable deklariert keinen virtual Destruktor, d.h. es ist nicht dafür vorgesehen, die Basis einer öffentlichen Vererbungskette zu sein. Erbe immer privat davon.

3voto

Adam Badura Punkte 4541

Ich denke, dass es aus einer höheren Perspektive public-Vererbung sein sollte. Die Gründe, es private zu machen, sind rein technisch.

Warum? Weil die Frage, ob ein Typ kopierbar ist oder nicht (und dies wird durch die Vererbung von boost::noncopyable gezeigt) Teil der öffentlichen Schnittstelle ist. Zum Beispiel, wenn die Vererbung public wäre, könnten Sie (mithilfe von "Metaprogrammierung") prüfen, ob der Typ von boost::noncopyable abgeleitet ist und dann darüber nachdenken, ob er kopierbar ist oder nicht.

Nikolai N Fetissov weist in seiner Antwort auf diese Frage hin, dass boost::noncopyable keinen virtual Destruktor hat und daher nicht als public Basisklasse verwendet werden sollte. Obwohl dies ein gültiges Argument im Allgemeinen ist, glaube ich, dass es so unwahrscheinlich ist, dass jemand jemals versuchen würde, ein Objekt (und delete insbesondere) über einen Zeiger auf boost::noncopyable zu verwenden, dass das Argument (in diesem speziellen Fall) rein theoretisch ist.

Komm schon! Wenn jemand so geneigt ist, Code zu missbrauchen, dass er delete auf einen Zeiger auf boost::noncopyable verwendet, gibt es keine Möglichkeit, sicher zu sein. Sicher, Sie können es ein wenig schwieriger machen, aber ein so entschlossener Programmierer wird sowieso einen anderen Weg finden, um den Code zu missbrauchen.

Außerdem scheint es in C++11 so zu sein, dass boost::noncopyable dieses Problem lösen könnte, indem ein default protected Destruktor deklariert wird:

protected:
    ~noncopyable() = default;

Auf diese Weise sollte kein zusätzlicher Aufwand für die Deklaration des Destruktors entstehen (da wir ihn auf default gesetzt haben), während wir vor delete auf einen Zeiger auf boost::noncopyable geschützt sind.

Andererseits scheint es jedoch auch unwahrscheinlich, dass jemand bereit sein wird zu überprüfen, ob ein Typ kopierbar ist, indem er die Vererbung von boost::noncopyable überprüft. Hauptsächlich, weil es keine vollständige Antwort liefert. Nur weil ein Typ nicht von boost::noncopyable abgeleitet ist, bedeutet das nicht, dass er kopierbar ist.

Beachten Sie auch, dass die Boost.Noncopyable-Dokumentation die Verwendung von private Vererbung vorschlägt.

3voto

Michael Ma Punkte 832

Laut dem Boost-Dokument

Es ist dazu gedacht, als private Basis verwendet zu werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X