2017-06-28 3 views
0

Warum funktioniert das "Cross-Cast" nicht?"Cross-Cast" Versuch mit statischen_cast fehlgeschlagen; Warum?

Die folgende schafft dieses Objekt Vererbungsmodell:

 FOOD 
    / \ 
CHEESE CAKE 

Hier versuche ich zu static_cast ein Zeiger von cheese zu cake, einen Käsekuchen machen: D. Ich erhalte die folgende Fehlermeldung von Apple Clang/LLVM:

ERROR: Static cast from 'Cheese *' to 'Cake *', which are not related by inheritance, is not allowed 

Aber sie durch Vererbung verwandt sind: sie Geschwister sind.

Warum kann ich warf einen cheese zu einem cake, wie ich eine int zu einem float werfen? Warum kann ich nicht von abgeleiteten Objekten, die von derselben Basisklasse erben, "cross-casten"?

Minimale, vollständige und überprüfbare Beispiel folgt, mit static_cast und dynamic_cast Versuche, Fehler zu markieren.

Antwort

0

Der Fehler sagt alles, ERROR: Static cast from 'Cheese *' to 'Cake *', which are not related by inheritance, is not allowed. Obwohl sie Geschwister sind, sind sie nicht durch Vererbung verwandt.

Wenn Sie unbedingt Käsekuchen machen möchten, können Sie mehrere Vererbung machen.

FOOD 
/ \ 
CHEESE CAKE 
    \ /
    CHEESECAKE 

So:

class CheeseCake : public Cake, public Cheese 
+1

Aber es ist zweimal die Kalorien, weil die Vererbung nicht virtuell ist :( – Quentin

+0

Ich möchte Cheescake nicht durch die Kombination der beiden machen; Ich möchte einen Käsekuchen ein '' Kuchen'' Objekt anstelle eines '' Käse nennen "Objekt. Ein bisschen ein verwirrendes Beispiel, erkenne ich rückblickend. – kmiklas

1

not related by inheritance auf demselben Zweig bedeuten würde ...

Sie sollten nicht verwechseln Werte Casting für Zeiger (oder umgekehrt) Gießen, sie sind verschiedene Arten Umwandlung.

Die int zu float eine Funktion verwendet, um einen Wert eines bestimmten Typs auf einen Wert des Zieltyps zu konvertieren (man beachte, dass diese Funktion explizit oder implizit sein kann, ist es implizit für diesen speziellen Fall, dh. Definiert in die Sprache). In C++ können Sie dies für benutzerdefinierte Klassentypen implementieren, indem Sie ein ctor für Klasse A implementieren, das einen Wert vom Typ B erhalten kann, oder einen Darstellungsoperator für Klasse B implementieren, der einen Wert vom Typ A zurückgibt.

Cake * bis Cheese * Werte nicht konvertieren, aber versucht, ein bestimmtes Objekt auf andere Weise anzuzeigen. Es ist Untertyp Polymorphismus (so müssen Sie dynamic_cast verwenden). Angesichts Ihrer Typhierarchie kann ein Cheese-Objekt einfach als Food-Objekt betrachtet (nicht konvertiert) werden, indem ein Food-Pointer auf ein Cheese-Objekt zeigt (so wie man von verschiedenen Personen unterschiedlich betrachtet werden kann) oder der Arzt kann Sie ergreifen, während Sie immer die gleiche Person sind!) Es ist klar (zumindest in Ihrer Hierarchie), dass ein Käse nicht als ein Kuchen betrachtet werden kann, wenn es der Fall wäre, wie das Käseobjekt reagieren würde Kuchen spezifische Methoden? Sie sind ein Tier, ein Hund auch, aber es ist schwer vorstellbar, dass ich Sie als Hund sehen kann (Sie haben nicht 4 Beine, nicht wahr?)

Do not lassen Sie sich von Ihrem Fall täuschen.Ok, es scheint, dass der Inhalt von Cheese und Cake identisch ist, aber die gegebene Hierarchie sagt die Wahrheit: Es gibt nicht auf dem gleichen Zweig, Sie können nicht einen Cheese-Zeiger von einem Kuchen-Zeiger bekommen. Der C++ - Compiler schützt Sie davor.

Jetzt ändern sich die Dinge ein wenig, wenn Sie mehrfache Vererbung wie eine CheeseCake verwenden, die von Käse und Kuchen erbt. Wenn dann ein CheeseCake-Objekt durch einen Cheese-Zeiger angezeigt wird, ist es möglich, es in einen Kuchenzeiger umzuwandeln, da ein CheeseCake beides ist! Natürlich kann selbst in diesem Szenario mit mehrfacher Vererbung ein Cheese-Objekt nicht als Cake through pointers angesehen werden.

+0

Aber gilt nicht die gleiche Logik für das Umsetzen von Werten? Nehmen wir an, wir konvertieren ein float zu einem int. Nun, können wir die Dezimalstelle auf einem int abschneiden? Erhalte den Bruchteil, finde seine Decke oder seinen Boden? Nein, keiner von diesen ergibt einen Sinn nach einer Umwandlung von float nach int ... aber wir tun es trotzdem. – kmiklas

+0

Ich habe dir gesagt, dass du beim Umwandeln * in einen anderen umwandelst Mit Zeiger gibt es keine Umwandlung! Bei einem Wert-Casting haben Sie zwei Werte, den ursprünglichen und den umgewandelten durch die Konvertierungsfunktion.Im Zeiger-Casting gibt es immer ein Objekt, aber zwei v Sie sehen darauf (ein Zeiger ist eine Ansicht auf ein Objekt), es gibt keine Transformation (ich kann Sie als OP sehen und einige Ihrer Freunde sehen Sie als Fußballspieler, dieselbe Person, zwei verschiedene Ansichten, es gibt keine Werttransformation , nur verschiedene Möglichkeiten, mit dir zu interagieren). –

Verwandte Themen