Polymorphie bezeichnet die Vielgestaltigkeit eines Objektes, von dem andere abgeleitet wurden. Insbesondere bedeutet es, dass derselbe Methodenaufruf verschiedene Auswirkungen haben kann. Erweitern wir also das vorherige Beispiel um Polymorphie:
{
CFruit()
{ m_r = m_g = m_b = 0.0f; }
{ }
{ cout << m_r <<
{ cout << "This is a Fruit" << endl; }
};
Diese Klasse funktioniert nicht für sich
alleine, da sie eine rein virtuelle Methode
Rein virtuelle Methoden wie
Die Methode
{
CBanana()
{ m_r = 1.0f; m_g = 1.0f; m_b = 0.0f; }
{ }
{ cout <<
{ cout <<
};
Jedes Mal, wenn jetzt die printType- oder printName-Methoden für eine Frucht aufrufen wird, die zufällig eine Banane ist, verzweigt unser Programm in die Unterroutinen, die wir für die Banane implementiert haben.
{
CApple()
{ m_r = 0.0f; m_g = 1.0f; m_b = 0.0f; m_worm =
{ }
{
cout <<
cout <<
}
};
Der Apfel bleibt bis auf die Implementierung der
Zusätzlich besitzt der Apfel noch ein Attribut
In diesem Beispiel gibt es jetzt die Funktion
{
fruit.printType();
fruit.printName();
fruit.printColor();
}
Warum übergeben wir
Wenn wir Parameter übergeben, dann entweder als Wert (by value) oder als Referenz bzw. Pointer (by reference).
Wenn wir
nur eine Referenz übergeben, ist die Welt in Ordnung, da wir
im Grunde nur eine Speicheradresse unseres Objektes weitergeben.
Schreiben wir noch ein
Übergeben wir ein Objekt als Wert, muss der Compiler irgendwo eine Kopie des Objekts anfertigen, während das Programm läuft. Erinnert euch daran, dass wir mit lokalen Variablen (als Wert übergeben) arbeiten können, ohne dass sich die Variable, die ursprünglich übergeben wurde, ändert.
Das funktionierte bisher wunderbar.
void printAll(CFruit fruit)
{
fruit.printType();
}
Ich habe mir angewähnt, komplexere Objekte als const reference zu übergeben, wenn ich in einer Funktion oder Methode nichts an ihnen ändere.
Möchte ich ein Objekt in einer Funktion verändern, übergebe ich es als Pointer. Auf diese Weise wird im Programmtext schon beim Aufruf durch das auftauchende & klar, dass hier etwas verändert wird.
- Ein Objekt, das irgendwo noch eine rein virtuelle
Funktion besitzt, kann nicht instanziiert werden. Versuche es, indem du
die printName-Methode aus
CApple temporär auskommentierst und das Projekt kompilierst. - Gebe in Konstruktor und Destruktor der Klassen
einen Text aus. Was passiert beim Aufruf der Funktion
printColor nicht, im Vergleich zum vorherigen Beispiel? - Implementiere die Methode
printAll als Bestandteil vonCFruit . - Was passiert, wenn der Destruktor von
CFruit versucht, die MethodeprintName aufzurufen? Warum? Kann man sie im Destruktor vonCApple aufrufen?