Kompilerbug?
-
class B { public: B* getB(){return b;} protected: int i; private: B* b; }; class C : public B { public: void foo(C* c) { B* b = c->getB(); i++; //geht natürlich c->i++; //geht auch b->i++; // geht nicht! Warum? static_cast<C*>(b)->i++; //geht wieder } };error C2248: "B::i": Kein Zugriff auf protected Member, dessen Deklaration in der B-Klasse erfolgte.
Warum habe ich kein Zugriff auf i von B, wenn ich ein B bin?
-
Das ist schon richtig so, bei protected darfst du zwar auf die eigenen geerbten Elemente zugreifen, aber nicht auf die von anderen Instanzen.
-
Von einem Compilerbug sollte man immer zuletzt ausgehen. Vor allem, wenn man sich bei einem Sprachmittel nicht sicher ist...

-
Athar schrieb:
Das ist schon richtig so, bei protected darfst du zwar auf die eigenen geerbten Elemente zugreifen, aber nicht auf die von anderen Instanzen.
Ich darf doch auf c->i++; zugreifen.
Nexus schrieb:
Von einem Compilerbug sollte man immer zuletzt ausgehen. Vor allem, wenn man sich bei einem Sprachmittel nicht sicher ist...

Na gut, dann Sprachbug.

-
äää? schrieb:
Athar schrieb:
Das ist schon richtig so, bei protected darfst du zwar auf die eigenen geerbten Elemente zugreifen, aber nicht auf die von anderen Instanzen.
Ich darf doch auf c->i++; zugreifen.
Ja, aber c ist eben ein Pointer auf eine Instanz der Klasse C - also greifst du auf das geerbte Member i zurück.
-
Objekte einer Klasse dürfen auf protected/private - Member anderer Objekte derselben Klasse zugreifen. Deshalb geht c->i++.
-
Hat das irgendeinen Grund, warum C nicht auf i von anderen B zureifen kann, wenn C eigentlich auch ein B ist?
-
äää? schrieb:
Hat das irgendeinen Grund, warum C nicht auf i von anderen B zureifen kann, wenn C eigentlich auch ein B ist?
Ja, natürlich hat es einen Grund.
Wäre es anders, könntest du
protectedganz einfach aushebeln, und (über eine Hilfsklasse) beliebig von aussen darauf zugreifen.
-
hustbaer schrieb:
äää? schrieb:
Hat das irgendeinen Grund, warum C nicht auf i von anderen B zureifen kann, wenn C eigentlich auch ein B ist?
Ja, natürlich hat es einen Grund.
Wäre es anders, könntest du
protectedganz einfach aushebeln, und (über eine Hilfsklasse) beliebig von aussen darauf zugreifen.Kann man das nicht so schreiben:
((C*)b)->i++;?
Oder ist das undefiniert?
-
wxSkip schrieb:
hustbaer schrieb:
äää? schrieb:
Hat das irgendeinen Grund, warum C nicht auf i von anderen B zureifen kann, wenn C eigentlich auch ein B ist?
Ja, natürlich hat es einen Grund.
Wäre es anders, könntest du
protectedganz einfach aushebeln, und (über eine Hilfsklasse) beliebig von aussen darauf zugreifen.Kann man das nicht so schreiben:
((C*)b)->i++;?
Oder ist das undefiniert?Ich würde sagen das ist undefiniert, da du nen Zeiger auf ein Objekt erzeugst und noch dazu dereferenzierst welches (so) nicht existiert.
(Es sei denn natürlich dass "b" auf ein echtes "C" zeigen würde, aber dann ist ja sowieso klar dass es OK und "erlaubt" ist.)
-
Also Up und Downcasts sind doch eine ganz legitime Geschichte, nur eben das Downcasts potentiell gefährlich sind.
Des weiteren wird eine Basisklasse ja immer zuerst erzeugt, dann der "Aufsatz".
Bei einem Downcast zu einer Ableitung, wo nur eine Basis liegt, kann man den reinen Basisteil auch ganz normal verwenden.@äää
Auch wenn so eine Ableitung eine ist-ein Beziehung abbilden soll, ist dem bei einer differenzierteren Betrachtung einfach nicht so. Du musst Konstrukt und Verwendungsmöglichkeiten auseinander halten. Tasächlich könnte man das ganze (auf den Ersten Blick) wie eine Klasse Vorstellen, welche Ihre Basis als Element enthält. Mal abgesehen von dem Protectedmechanismus hat die Subklasse ja den gleichen Zugrif auf seine Basis wie irgendeine andere klasse auf ein Objekt der Basis. Wenn du mal Ausgaben in Konstruktoren und Destruktoren einfügst, wirst du feststellen das bei einer Klassenheirarchie jedes Objekt für sich erstellt wird. Die Instanziierung der Klasse C aus deinem Beispiel hat demanch 2 Konstruktoraufrufe und 2 Destruktoraufrufe zur Folge.
Aber wie gesagt, ist nur auf dem Ersten Blick so als hätte man die Basis als Element.Wäre ein C ein B könnte C bei (beinhaltenden) Bs auch auf private Elemente zugreifen, wie es Die Bs bei beinhaltenden anderen B-Objekten auch können.
Verstehe mich nicht falsch, das fegt die Ist-Ein Beziehung nicht vom Tisch.
Aber diese entsteht lediglich durch die Verwendungsmöglichkeiten für dieses Konstrukt wie Polymorphie usw.Diese "Ist-Ein Beziehung" kommt halt dadurch zustande, dass man solche Konstrukte eben polymorph zum Beispiel. Dazu gibt es dann auf der Konstruktionsseite dan auch einige Hilfen wie virtuelle Methoden und Abstraktheit usw.