Rufen Sie eine Childs-Version einer Funktion anstelle eines Elternteils auf?

8

Okay, also habe ich zwei Klassen bekommen.

%Vor%

Und eine Reihe von Eltern mit einem Kind

%Vor%

Dann rufe ich print an und möchte, dass es Hallo Welt sagt.

%Vor%

Aber es ruft die Eltern an. Wie behebe ich das?

    
CyanPrime 13.04.2011, 04:30
quelle

4 Antworten

11

Dies kann behoben werden, indem die Funktion virtuell deklariert wird, a la:

%Vor%

So implementiert man Polymorphie in C ++. Mehr hier: Ссылка

Beachten Sie jedoch, dass in Ihrem Beispiel die untergeordnete Funktion nie aufgerufen wird, da Sie Objekt -Werte verwenden, keine Zeiger / Verweise auf Objekte. Um dies zu beheben,

%Vor%

Dann:

%Vor%     
Roadrunner-EX 13.04.2011, 04:39
quelle
2

Was Sie suchen, ist Laufzeitpolymorphismus, was bedeutet, dass das Objekt "viele Formen" (d. h. a oder b) annehmen und entsprechend reagieren muss, wenn das Programm läuft. In C ++ führen Sie dazu die Funktion virtual in der Basisklasse a :

aus %Vor%

Dann müssen Sie die Elemente nach Zeiger oder Verweis speichern, und - wie im Allgemeinen können die abgeleiteten Klassen neue Datenelemente einführen und benötigen mehr Speicher - ist es normal, die Objekte auf dem Haufen mit new zu erstellen:

%Vor%

Dann können Sie anrufen:

%Vor%

Und es wird die b Implementierung von print() aufgerufen.

Sie sollten später delete blah[5] (und alle anderen, auf die Sie hingewiesen haben, auf den von new zurückgegebenen Speicher verweisen).

In der Praxis ist es eine gute Idee, einen Container zu verwenden, der die Objekte löschen kann, die er enthält, wenn er selbst zerstört wird, sei es, weil er den Bereich verlässt oder gelöscht wird. std::vector<> ist ein solcher Container. Sie können Smart-Pointer auch verwenden, um das Löschen der Objekte a und b zu automatisieren. Dies hilft, den Code korrekt zu machen, wenn Exceptions ausgelöst werden, bevor Ihre delete -Anweisungen ausgeführt werden, und Sie möchten, dass Ihr Programm weiter läuft, ohne Speicher zu verlieren. Die Boost-Bibliothek ist der einfachste / beste Ort, um eine intelligente Pointer-Implementierung zu erhalten. Zusammen:

%Vor%

(Es ist normaler, Vektoren mit push_back() zu verwenden, da der Vektor automatisch so vergrößert wird, dass er in alle hinzugefügten Elemente passt, wobei die neue Summe durch Aufruf von vector::size() verfügbar ist.)

    
Tony Delroy 13.04.2011 04:42
quelle
0

Dies geschieht, weil Sie dem Compiler mitgeteilt haben, dass Ihre Instanz vom Typ a ist. Es ist in einem Array von a -Objekten, oder? Es ist also vom Typ a !

Natürlich möchten Sie, dass die Methode in b den Wert in a überschreibt, obwohl Sie einen Verweis auf den übergeordneten Typ haben. Sie können dieses Verhalten mithilfe des Schlüsselworts virutal für die Funktionsdeklaration in der übergeordneten Klasse ermitteln.

%Vor%

Warum funktioniert das?

Wenn Sie Ihr Objekt in die Elternklasse umgewandelt haben, haben Sie eine Mehrdeutigkeit eingeführt. Wenn das print() dieses Objekts aufgerufen wird, wie sollen wir es behandeln? Es ist vom Typ b , aber die Referenz ist vom Typ a , daher erwartet der Umgebungscode, dass er sich wie a verhält, nicht b !

Um zu disambiguieren, wird das Schlüsselwort virtual eingeführt. virtual Funktionen werden immer überschrieben, wenn das Objekt einer Kindklasse angehört, die eine Methode mit der gleichen Signatur enthält.

Prost!

    
slezica 13.04.2011 04:39
quelle
-1

Deklarieren Sie a::print() als virtuell und verwenden Sie Zeiger / Referenz , um die Funktion print() aufzurufen. Wenn Sie blah[5] = b() ausführen, wird Objekt-Slicing ausgeführt. Sie haben keine Wirkung, wenn Sie eine virtuelle Funktion über ein Objekt aufrufen.

    
iammilind 13.04.2011 04:38
quelle

Tags und Links