Ich habe eine Frage darüber, wie ein C ++ - Compiler weiß, wie viel Platz er für ein Objekt bei der Vererbung reservieren muss.
Stellen Sie sich die folgenden Klassen vor, für einen Erwachsenen und ein Kind, die eine Personenklasse erweitern, aber wo ein Kind ein kurzes Buch mit ihnen hat.
%Vor%Wenn Sie jetzt ein Array von Person-Objekten erstellen und Objekte zu ihnen hinzufügen:
%Vor%Meine Frage ist: Woher weiß der Compiler, wie viel Speicherplatz benötigt wird, um sicherzustellen, dass das Array ein zusammenhängender Speicherblock ist, wenn er nicht weiß, ob das Array mit Adult- oder Child-Objekten (Objekte unterschiedlicher Größe) gefüllt wird?
Ich hoffe, das macht genug Sinn zu beantworten ...
Danke
Wie weiß der Compiler, wie viel Speicherplatz benötigt wird, um sicherzustellen, dass das Array ein zusammenhängender Speicherblock ist, wenn er nicht weiß, ob das Array mit
gefüllt wirdAdult
oderChild
Das Array people
darf keine Objekte Adult
oder Child
enthalten: es kann nur Person
Objekte enthalten.
Wenn Sie die Zuweisung people[0] = child1;
ausführen, werden die Person
-Teile des child1
-Objekts people[0]
zugewiesen. Alle Child
Teile werden effektiv ignoriert.
Dieses Verhalten, bei dem nur die Basisklassen-Teile eines Objekts kopiert werden, wird "Slicing" genannt.
Um polymorphes Verhalten in C ++ zu erhalten, müssen Sie entweder Pointer als Referenzen verwenden. Da es unmöglich ist, ein Array von Referenzen zu haben, müssten Sie ein Array von Zeigern verwenden.
Da Ihr Array vom Typ Person ist, weiß der Compiler nicht , genug Platz für Kinder und Erwachsene anzugeben. Es erklärt einfach genug für zwei Personen.
Jedes Mal, wenn Sie ein Kind oder einen Erwachsenen aufnehmen, wird das Objekt "abgeschnitten", wobei nur der Personenteil des Objekts beibehalten wird.
Der übliche Weg, dies zu umgehen, besteht darin, ein Array von People-Zeigern zu deklarieren (die alle konstante Größe haben, unabhängig davon, worauf sie zeigen, da sie wirklich nur Speicheradressen sind), die auf Objekte von beliebigen verweisen können Ihre Klassen.
Wenn Sie kein Array von Zeigern erstellen, weist Person people[2];
genug Platz für 2 Objekte vom Typ Person zu.
Wenn Sie der Person ein Kind zuweisen, werden nur die Person Merkmale von Kind kopiert .
Das ist eine ausgezeichnete Frage.
Die Antwort ist, dass es nicht so ist. Es hat nur Platz für die Felder der People-Klasse reserviert. Wenn Sie ein Kind hineinkopieren, werden nur die People-Teile (hehe) kopiert. Siehe Was ist Objekt-Slicing? .
Wenn Sie wirklich diese Operation ausführen möchten, sollten Sie wahrscheinlich Zeiger verwenden.
Die Aufgabe, die Sie gezeigt haben, macht nicht viel Sinn. Ja, das Array, wie Sie es anzeigen, wird zusammenhängend sein, aber es wird keinen Platz für die abgeleiteten Klassenmitglieder haben, und wenn Sie diese Zuweisung durchführen, werden diese Daten gelöscht (wenn der Compiler es sogar zulässt, was ich bin nicht sicher, dass es wird).
Kurz gesagt gibt es in C ++ keinen virtuellen Konstruktor. Beim Erstellen eines Objekts müssen Sie genau wissen, was Sie erstellen. Sobald das Objekt erstellt wurde, können Sie das von der Polymorphie abgeleitete klassenspezifische Verhalten aus einer Basisklasse verwenden. In Ihrem Fall wird beim Erstellen eines Person
-Objekts nur ein Person
-Objekt erstellt. Wenn Person
eine rein virtuelle Methode hat, wird der Compiler es nicht erstellen.
Falls Sie sich nicht sicher sind, ob Sie ein Parent
oder ein Child
Objekt erstellen möchten, können Sie eine polymorphe Zusammenfassung PersonFactory
verwenden, obwohl Sie beim Erstellen der Factory genau wissen müssen, was Art des konkreten Objekts, das Sie erstellen.
Tags und Links c++ inheritance compiler-construction memory-management