technische Aspekte der 'isa' in c ++
-
27-09-2019 - |
Frage
was genau bedeutet es, von technical point of view
, verstand ich, dass es bedeutet, dass mein derived class
immer base class
umgewandelt werden kann, dass es? Ich las einige Materialien ohne Bezug auf technische Aspekte, nur Philosophie! Vielen Dank im Voraus
Lösung
es bedeutet, dass meine abgeleitete Klasse kann immer auf Basisklasse umgewandelt werden
Eigentlich bedeutet es besser als das. int
kann immer zu float
umgewandelt werden, aber das bedeutet nicht, ein int „ist ein“ float. Es bedeutet nur ein Schwimmer kann aus einem int aufgebaut werden. Ebenso können Sie benutzerdefinierte Klassen, die konvertieren, aber keine andere Beziehung haben.
Mit Vererbung, ein Zeiger oder Verweis auf die abgeleitete Klasse kann immer auf einen Zeiger oder eine Referenz auf die Basisklasse umgewandelt werden [*]. Das heißt, kann ein Objekt der abgeleiteten Klasse anstelle eines Objekts der Basisklasse stehen. Es ist tatsächlich eines dieser Dinge. Wenn eine Person in einem Gehirnchirurgen stehen kann, dann sind sie ein Gehirnchirurg.
Eine formale Definition, wenn "a" ist Barbara Liskov Substitutionsprinzip . Was allerdings noch Philosophie, aber es ist sehr solide Philosophie und es bezieht sich direkt auf, wie Sie Programme schreiben.
Die andere Sache, die Sie gerade zu halten, wenn Vererbung in C ++ ist der Unterschied zwischen Runtime-Polymorphismus (erreicht mit virtual
Funktionen) und statischem Polymorphismus (die eigentlich keine Vererbung überhaupt erforderlich). Mit nicht-virtuellen Funktionsaufrufen, die Version der Funktion aufgerufen ist immer die Version in der Klasse definiert, dass die Compiler gesagt wird das Objekt (den statischen Typen). Dies könnte nicht wirklich korrekt funktionieren, wenn es in der abgeleiteten Klasse überlastet ist. Mit virtuellen Anrufe, die so genannte Version ist die Version in der Klasse definiert das Objekt tatsächlich ist (der dynamische Typ). Es ist wichtig, welche der beiden Arten von „ist ein“ Sie sind mit dem Ziel zu.
[*] und das Objekt sein wirksam zugänglich durch den Zeiger, das ist. Sie können immer coerce Zeigertypen mit reinterpret_cast
, aber das ist nicht das, was ich hier meine. Und es gibt einige knifflige Details - wenn die Basisklasse nicht eindeutig ist, dann können Sie den Zeiger auf einmal nicht konvertieren, aber man kann es explizit tun mehrere eindeutige Casts mit. Wenn die Basisklasse nicht zugänglich ist, dass Sie dann können konvertieren, aber nur mit einem C-Casts, nicht implizit. Die C-Casts wirkt wie ein static_cast
die Zugänglichkeit ignoriert, nicht wie ein reinterpret_class
. So haben Sie einen Arbeits Zeiger, aber hoffentlich auch ein starkes Gefühl, dass man etwas sehr falsch machen; -)
Andere Tipps
A abgeleitet ist, kann Klasse nur eine zugängliche und eindeutige Basisklasse an einem bestimmten Punkt umgewandelt wird R. Es gibt keinen Mangel an Referenzen und welche anderer Ort als der C ++ Standard selbst.
10,2 $ ist eine gute Referenz: A abgeleitet Klasse kann selbst dienen als Basisklasse vorbehaltlich der Zugangskontrolle; siehe 11.2. EIN Zeiger auf eine abgeleitete Klasse kann sein implizit umgewandelt in einen Zeiger auf eine zugängliche eindeutige Basisklasse (4.10). Ein L-Wert von einer abgeleiteten Klasse Typ kann ein Verweis auf ein gebunden werden zugänglich eindeutige Basisklasse (8.5.3). -Ende note]
Und wieder
$ 10.3 - „Die Basis-Bezeichner-Liste gibt den Typ der Basisklasse Subobjekte in einem Objekt enthaltenen die abgeleitete Klasse-Typ. [..] Hier wird ein Objekt der Klasse Derived2 wird ein Subobjekt der Klasse abgeleitet, die in wiederum ein Subobjekt der Klasse Base. [...]
Im Hinblick auf den OOAD Prinzipien:
Ich persönlich würde empfehlen Robert Martin Artikel für immer einen guten Halt auf diesem vor allem des OCP-Prinzip . Es ist mir nicht möglich, die Klarheit und Autorität zu schlagen, mit denen der Autor dieser legendären OOAD Richtlinien
erklärtbei LSP Schauen Sie auch wie in @Steves' Post erklärt