2010-03-21 5 views
5

ich dies aus C++ FAQSollte ich von einer privaten abgeleiteten Klasse auf seine Basisklasse zoomen?

Im Allgemeinen gefunden, Nr

Von einer Memberfunktion oder Freund einer privat abgeleiteten Klasse, die Beziehung zu der Basisklasse ist bekannt, und die Aufwärtskonvertierung von PrivateDer * zu Base * (oder PrivateDer & zu Base &) ist sicher; nein Guss wird benötigt oder empfohlen.

jedoch Benutzer von PrivatelyDer diese unsichere Umwandlung vermeiden sollten, da es auf einer privaten Entscheidung von PrivatelyDer basiert, und wird ohne vorherige Ankündigung geändert werden.

Wie kann man die obigen Wörter verstehen? Ich denke nicht, dass die Erklärung richtig oder genau ist.

Ich habe einen Code wie diese

class A{ 
}; 

class B: private A{ 
}; 

int main(){ 

    B *b = new B(); 
    A *a = new A(); 

    a = b;     //wrong 
    a = (A*)b;   //right 

} 
+2

Die implizite Umwandlung nicht kompiliert (A ist unzugänglich Basis), und die zweite wird mit einem C-Casts, dass das Äquivalent von 'hier reinterpret_cast'? – UncleBens

+0

Ja, du hast Recht, interpretieren Besetzung ist böse, wie wir alle wissen. Was er in der letzten Zeile getan hat, ist keine gute Praxis –

Antwort

4

Aus rein mechanischer Sicht haben Sie Recht: Eine Besetzung in eine private Basisklasse wird funktionieren und Arbeitsergebnisse produzieren.

Der Punkt der FAQ ist, dass es aus Sicht des Designs im Allgemeinen falsch ist. Private Vererbung soll eigentlich privat sein - mit anderen Worten, obwohl es funktionieren mag, sollte man nicht wissen, dass es funktioniert, und irgendwann kann es aufhören zu arbeiten - da es offiziell ein Implementierungsdetail ist, nicht Als Teil der öffentlichen Schnittstelle könnten sie die Klasse ohne Vererbung erneut implementieren. An diesem Punkt würde die Besetzung nicht mehr funktionieren (aber weil du eine Besetzung benutzt hast, warnt der Compiler wahrscheinlich nicht davor, dass du von etwas, das du wahrscheinlich nicht machen solltest, zu etwas übergegangen bin, das unmöglich funktionieren könnte überhaupt).

Edit: Ja, die Besetzung tut unbedingt funktionieren. Gemäß §5.4/7 der Norm:

...die folgende static_cast und reinterpret_cast Operationen (gegebenenfalls durch eine const_cast Operation folgt) können, Notation von expliziten Typ Umwandlung mit Hilfe der Gussdurchgeführt werden selbst wenn die Basisklasse Typ ist nicht zugänglich:

- ein Zeiger auf ein Objekt des abgeleiteten Klassentyps oder eines lvalue des abgeleiteten Klassentyps kann explizit in einen Zeiger oder Verweis auf einen eindeutigen Basisklassen-Typ, , konvertiert werden;

[Hervorhebung hinzugefügt]

+0

Nein, die Besetzung wird nicht unbedingt funktionieren. –

+0

Richtig, lernte heute etwas Neues. :-) –

+0

@Konrad: eine dieser seltenen Zeiten, in denen ich nicht sicher bin, etwas Neues zu lernen, war so eine großartige Sache! Ich wünschte fast, ich wüsste es nicht, denn dann würde es keine Versuchung geben, es zu benutzen. :-) –

1

Ich denke, dass die Erklärung richtig ist. Es heißt zwar, dass eine Besetzung von B bis A möglich ist, aber nicht getan werden sollte. Der Grund dafür ist, dass die Vererbung private ist und als ein Implementierungsdetail von B betrachtet werden sollte, das die Benutzer der Klasse nie interessieren sollten. Es sind genau die gleichen Regeln wie alles, was mit private markiert ist - es sollte als intern in der Klasse betrachtet werden. Externe Clients sollten sich nur auf die public Funktionen und Attribute verlassen - einschließlich public Vererbung.

Persönlich habe ich nie eine Verwendung für private Vererbung gefunden - ich denke, dass es oft besser ist, Komposition zu verwenden.

+0

@Anders: Private Vererbung macht Sinn, wenn sie mit Policy-Klassen gekoppelt ist (wie zB 'std :: allocator'): solche Klassen sind oft leer. Wenn Sie sie als private Mitglieder verwenden, würden sie immer noch Speicher verbrauchen, da jedes Mitglied einer Klasse eine eindeutige Adresse haben muss, selbst wenn das Mitglied den Speicher nicht benötigt. Vererbt man von ihnen jedoch, wird * nicht * unnötiges Gedächtnis verbrauchen. –

Verwandte Themen