Klassen Templates
-
Daaanke!!!
Fraaaage:
(eher Feststelltung, ob das so richtig ist:)
Nun wird in ignos Beispiel ein Vector über eine vererbte Klasse benutzt.
In dem C++ Programmierer (S. 267) steht allerdings:
"C-Arrays sind keine Klasse. Der Compiler reserviert sich für den Speicher nur sizeof(Oberklasse), aber nicht sizeof(Unterklasse)."Vektoren sind ja keine C-Array. Vektoren reservieren also problemlos auch genügend für die geerbten Unterklassen??
uuuuiiiiiiisind die mächtig
-
Nun wird in ignos Beispiel ein Vector über eine vererbte Klasse benutzt.
Wie meinst du das? In ignos Beispiel ist
vierte
selbst ist nicht polymorph, sondern nimmt nur in Memberfunktionen eine Referenz auf eine Basisklasse.Vektoren reservieren also problemlos auch genügend für die geerbten Unterklassen??
Natürlich. Basisklassen sind nur ein Subobjekt der ableitenden Klasse.
"C-Arrays sind keine Klasse. Der Compiler reserviert sich für den Speicher nur sizeof(Oberklasse), aber nicht sizeof(Unterklasse)."
Völliger Unsinn, oder du hast ohne Kontext zitiert (wahrscheinlicher).
Solltest du ein Array von (Unter)klassen anlegen, wird auf jeden Fall das komplette Objekt angelegt - versprochen. Alles andere wäre Unfug.
Zeig doch mal, wo genau du das her hast, das scheint irgendwie falsch zitiert worden zu sein.
Edit: Da verwechsle ich glatt Unter- und Oberklasse...
-
ups, verguckt. Natürlich nicht die Klasse vierte, die erbt ja nix. Sondern die erste oder zweite. Und darüber ein Vektor:
std::vector<erste> test2; test2.push_back(erste(2,3,4)); test2.push_back(erste(4,5,1)); vierte test4(test2[0],test2[1]); std::cout << test4.b <<"\n";
Das geht!
Ja, das ist natürlich aus dem Zusammenhang.
Es geht um solche Arrays:Oberklasse* array=new Unterklasse[4]; // sinnlos
"Die nichtgeerbten Attribute eines Unterklassenobjekts sind nicht zugreifbar, weil nur die Oberklassenanteile abgespeichert werden. Die Adressen &array[i] (0<=i<=4) liegen nur sizeof(Oberklasse) Bytes auseinander, nicht sizeof(Unterklasse)."
Wahrscheinlich weil es statisch ist.
Vektoren sind aber ganz schön mächtig.
-
Autor schrieb:
Die nichtgeerbten Attribute eines Unterklassenobjekts sind nicht zugreifbar, weil nur die Oberklassenanteile abgespeichert werden.
Das ist falsch. Gespeichert werden vier hintereinander liegende Unterklassen-Objekte.
Die Adressen &array[i] (0<=i<=4) liegen nur sizeof(Oberklasse) Bytes auseinander, nicht sizeof(Unterklasse).
Ja, das ist ja auch klar. Aber
array[1]
ist ein nicht erlaubter Ausdruck der undefiniertes Verhalten erzeugt, denn man dereferenziert da implizit einen ungültigen Zeiger. Das heißt, solche array-to-pointer-decays sollte man hübsch sein lassen.Wahrscheinlich weil es statisch ist.
Was ist da statisch?
-
Lymogry schrieb:
Es geht um solche Arrays:
Oberklasse* array=new Unterklasse[4]; // sinnlos
"Die nichtgeerbten Attribute eines Unterklassenobjekts sind nicht zugreifbar, weil nur die Oberklassenanteile abgespeichert werden. Die Adressen &array[i] (0<=i<=4) liegen nur sizeof(Oberklasse) Bytes auseinander, nicht sizeof(Unterklasse)."
Wahrscheinlich weil es statisch ist.
was du hier schreibst dürfte gar nichterst kompilieren.
es nennt sich downcasting und ist - im gegensatz zu upcasting - nicht implizit vollstreckbar. wenn du dir sicher bist, dass deine (Unterklasse*)-ptr in wirklichkeit auf objekte vom typ Oberklasse zeigen, dann kannst du dynamic_cast<Oberklasse*>(ptr) schreiben. wenn du jedoch weisst, dass deine (Unterklasse*)-ptr das nicht tun, dann macht es wenig sinn downzucasten und ist auch - ausser mit einem hack den ich dir nicht verrate - nicht möglich.
-
Oberklasse bezeichnet die Basisklasse. Das ist kein down- sondern upcasting. Das habe ich auch verwechselt.
-
achso, ups mein fehler
edit: doch doch das macht schon sinn. kleines codebeispiel:
#include <iostream> struct base { virtual ~base() { } virtual void print() const { std::cout << "i'm a base"; } }; struct derived : base { virtual void print() const { std::cout << "i'm derived"; } }; int main() { base* array = new derived[4]; array[2].print(); delete[] array; }
und die ausgabe:
i'm derived
das zeigt dass über den zeiger auf eine basisklasse die methode der abgeleiteten klasse aufgerufen wurde. jedoch kannst du über einen zeiger auf die basisklasse (direkt zumindest) nur die methoden und member der basisklasse benutzen (wenn diese mit virtual in der abgeleiteten klasse überschrieben werden ist es etwas anderes).
-
Das funktioniert zufaellig, weil
derived
undbase
beide gleich gross sind.Hier auf Ideone eine andere Variante, die natuerlich abstuerzt.