C ++, das Platz für Objekte unter Verwendung der Vererbung zuweist

8

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

    
Freddie 30.07.2011, 17:14
quelle

6 Antworten

12
  

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 Adult oder Child

gefüllt wird

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.

    
James McNellis 30.07.2011, 17:16
quelle
3

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.

    
Cameron 30.07.2011 17:17
quelle
1

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 .

    
Yochai Timmer 30.07.2011 17:17
quelle
1

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.

    
El Marcel 30.07.2011 17:18
quelle
0

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).

    
Reinderien 30.07.2011 17:17
quelle
0

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.

    
doron 30.07.2011 17:27
quelle