08.05.2000 Universität Dortmund, Lehrstuhl Informatik 1 [email protected] EINI II...
-
Upload
hludowig-bohning -
Category
Documents
-
view
112 -
download
2
Transcript of 08.05.2000 Universität Dortmund, Lehrstuhl Informatik 1 [email protected] EINI II...
08.05.2000
Universität Dortmund, Lehrstuhl Informatik [email protected]
EINI IIEinführung in die Informatik
für Naturwissenschaftler und Ingenieure II
Prof. Dr. Gisbert Dittrich
16-2
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Gliederung: Virtuelle Methoden
• Bindung von Objekten (möglich): – Unterklasseobjekt an Oberklasseobjekt zu binden
• Bindung von Methoden:– statisch (zur Übersetzung)
– dynamisch (zur Laufzeit) --> virtuelle Methoden
• Beispiel: Früchte: - konventionell - mit virtuellen Methoden
• Phänomene bei der Verwendung virtueller Methoden– virtuell wirkt nur bei Einsatz von Zeigern– virtuelle Methode muß nicht notwendig neu definiert werden– rein virtuelle Methoden: Syntax. "= 0"
müssen später (re)definiert werden Objekte nur zu Klassen instanziierbar, für die Methoden definiert sind.
16-3
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Beispiel: Früchte
• Zu berücksichtigende Klassifikation:• Hülsenfrüchte: Erbsen, Bohnen
• Obst: Äpfel, Birnen– Südfrüchte: Apfelsinen, Bananen
• Attribut(e): • die Frucht
• Methoden• Konstruktoren• Druck
– druckt den Namen der Frucht und die Zugehörigkeit zur Klasse
16-4
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Klassifikationshierarchie
HülsenfrüchteMethode: Druck()
SüdfrüchteMethode: Druck()
ObstMethode: Druck()
FrüchteAttribut: dieFruchtMethode: Druck()
16-5
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Gemeinsam
• char * dieFrucht. Für alle Objekte der Klassenhierarchie zugreifbar.
--> protected
• Druck • sollte (letztendlich) für jedes Objekt angeben, aus welcher Klasse es stammt.
16-6
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Deklaration der Klasse Frucht
class Frucht {
protected:
char * dieFrucht;
public:
Frucht(char *);
void Druck();
};
KonstruktorName der konkreten
Frucht
16-7
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Sieht nach, wie lang die Zeichenkette sein muß, allokiertentsprechend
Kopiert dasArgument in dieneue Zeichenkette
Deklaration der Methoden
// int strlen(char *);
// void strcpy(char *, char *); Frucht::Frucht(char * s) {
dieFrucht = new char[strlen(s)];
strcpy(dieFrucht, s);
}
16-8
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Deklaration der Methoden
void Frucht::Druck() {
cout << "(Frucht) "
<< dieFrucht << endl;
}
16-9
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Deklaration der Klasse Hfrucht
class Hfrucht: public Frucht {public:
Hfrucht(char *);void Druck();
};
Hfrucht::Hfrucht(char * s) : Frucht(s) {}
void Hfrucht::Druck() {cout << "(Hfrucht) "
<< dieFrucht << endl;}
Oberklasse istFrucht, erben
ist public
Konstruktor für Hfrucht
nur Aufruf desKonstruktors der
Oberklasse
Neudefinition der Methode
Druck
16-10
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Weitere Deklarationen
• Klasse Obst als Unterklasse von Frucht: völlig analog zum Vorgehen bei Frucht
• Klasse Suedfruechte als Unterklasse von Obst: Vorgehen ebenfalls völlig analog.
16-11
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Hauptprogramm
Frucht * ruebe = new Frucht("Rübe");
ruebe->Druck();
Hfrucht * erbse = new Hfrucht("Erbse");
erbse->Druck();
Obst * apfel = new Obst("Apfel");
apfel->Druck();
SuedFrucht * banane = new SuedFrucht("Banane");
banane->Druck();
Ausgabe: (Frucht) Rübe(Hfrucht) Erbse(Obst) Apfel(Südfrucht) Banane
16-12
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
(jeder Apfel ist Frucht etc.)
Hauptprogramm (Forts.)
Ausgabe:
(Frucht) Frucht
(Frucht) Apfel(Frucht) Erbse(Obst) Obst(Obst) Banane
Frucht * f = new Frucht("Frucht");
f->Druck();
f = apfel; f->Druck();
f = erbse; f->Druck();
Obst * g = new Obst("Obst");
g->Druck();
g = banane; g->Druck();
16-13
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Vorlage EED EINI II, SS 99; // überarbeitet: GD 20.4.00// demonstriert Vererbung:
// noch ohne virtuelle Methoden
#include <iostream.h>#include <stdio.h>
void strcpy(char * nach, char * von);int strlen(char * r);
class Frucht {protected:
char * dieFrucht;public:
Frucht(char *);void Druck();
};
Frucht::Frucht(char * s) {dieFrucht = new char[strlen(s)];strcpy(dieFrucht, s);}
void Frucht::Druck() {cout << "(Frucht) " << dieFrucht <<
endl;}
// -------------------------------------------
class Hfrucht: public Frucht {public:
Hfrucht(char *);void Druck();
};
Hfrucht::Hfrucht(char * s) : Frucht(s) {}
void Hfrucht::Druck() {cout << "(Hfrucht) " << dieFrucht
<< endl;}
// -------------------------------------------
class Obst: public Frucht {public:
Obst(char *);void Druck();
};
Obst::Obst(char * s) : Frucht(s) {}
void Obst::Druck() {cout << "(Obst) " << dieFrucht <<
endl;}
// -------------------------------------------
class SuedFrucht: public Obst {public:
SuedFrucht(char *);void Druck();
};
SuedFrucht::SuedFrucht(char * s) : Obst(s) {}
void SuedFrucht::Druck() {cout << "(Suedfrucht) " <<
dieFrucht << endl;}
// -------------------------------------------
int main() {cout << "\nZuweisungen: \n";Hfrucht * erbse = new
Hfrucht("Erbse"); erbse->Druck();Obst * apfel = new Obst("Apfel");
apfel->Druck();SuedFrucht * banane = new
SuedFrucht("Banane"); banane->Druck();cout << "\nhier: ";cout << "\nZuweisung an Zeiger auf
Frucht: \n";Frucht * f = new Frucht("Frucht");f->Druck();f = apfel; f->Druck();f = erbse; f->Druck();cout << "\nda: ";cout << "\nZuweisung an Zeiger auf
Obst: \n";Obst * g = new Obst("Obst"); g-
>Druck();g = banane; g->Druck();
cout << "fertig";}
// ---------------------------------------------
void strcpy(char * nach, char * von) {while (*nach++ = *von++);
}
int strlen(char * r) {int f = 0;while (r[f++]);return f;}
16-14
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 1
class Frucht {protected:
char * dieFrucht;public:
Frucht(char *);void Druck();
};
Frucht::Frucht(char * s) {dieFrucht = new char[strlen(s)];strcpy(dieFrucht, s);}
16-15
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 2
void Frucht::Druck() {cout << "(Frucht) " << dieFrucht
<< endl;}
class Hfrucht: public Frucht {public: Hfrucht(char *); void Druck();};
Hfrucht::Hfrucht(char * s): Frucht(s) {}
void Hfrucht::Druck() {cout << "(Hfrucht) " << dieFrucht
<< endl;}
16-16
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 3
class Obst: public Frucht {public:
Obst(char *); void Druck();};
Obst::Obst(char * s) : Frucht(s) {}
void Obst::Druck() {cout << "(Obst) " << dieFrucht
<< endl;}
16-17
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 4
class SuedFrucht: public Obst {public:
SuedFrucht(char *);void Druck();};
SuedFrucht::SuedFrucht(char * s) : Obst(s) {}
void SuedFrucht::Druck() {cout << "(Suedfrucht) "
<< dieFrucht << endl;}
// -------------------------------------------
int main() {cout << "\nZuweisungen: \n";Hfrucht * erbse = new
Hfrucht("Erbse"); erbse->Druck();Obst * apfel = new Obst("Apfel");
apfel->Druck();SuedFrucht * banane = new
SuedFrucht("Banane"); banane->Druck();cout << "\nhier: ";cout << "\nZuweisung an Zeiger auf
Frucht: \n";Frucht * f = new Frucht("Frucht");f->Druck();f = apfel; f->Druck();f = erbse; f->Druck();cout << "\nda: ";cout << "\nZuweisung an Zeiger auf
Obst: \n";Obst * g = new Obst("Obst"); g-
>Druck();g = banane; g->Druck();
cout << "fertig";}
// ---------------------------------------------
void strcpy(char * nach, char * von) {while (*nach++ = *von++);
}
int strlen(char * r) {int f = 0;while (r[f++]);return f;}
16-18
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 5 int main() {
cout << "\nZuweisungen: \n";Hfrucht * erbse =
new Hfrucht("Erbse"); erbse->Druck();Obst * apfel = new Obst("Apfel");apfel->Druck();SuedFrucht * banane =
new SuedFrucht("Banane"); banane->Druck();
cout << "\nhier: ";
16-19
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 6; main-Fortsetzung
cout << "\nZuweisung an Zeiger auf Frucht: \n";
Frucht * f = new Frucht("Frucht");f->Druck();f = apfel; f->Druck();f = erbse; f->Druck();cout << "\nda: ";cout << "\nZuweisung an Zeiger auf
Obst: \n";Obst * g = new Obst("Obst"); g->Druck();g = banane; g->Druck();
cout << "fertig";}
Fruechte_nicht_virtuell
16-20
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte, ohne virtuelle Methoden// Fortsetzung 7
void strcpy(char * nach, char * von) {while (*nach++ = *von++);}
int strlen(char * r) {int f = 0;while (r[f++]);return f;}
16-21
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Was lernen wir daraus?
• Zuweisungen sind entlang der Vererbungs-hierarchie möglich:
Ein Objekt einer Klasse kann einem Objekt einer Oberklasse zugewiesen werden.
• Bei der Ausführung von Methoden wird statisch vorgegangen:
Die Methode des Objekts wird ausgeführt, die schon zur Übersetzung zu erkennen war.
16-22
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Statische Methodenausführung
Frucht * f
Frucht-Druckfür f
Zuweisung von
apfel (Obst)an f
Hier also Auswahl derMethode zur Definitions-
zeit.
16-23
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Bindungen
•statisch: Die Methode, die zur Zeit der Klassendefinition für das Objekt definiert wurde, wird verwendet.
•dynamisch: Die Methode, die zur Zeit der Benutzung für das Objekt verfügbar ist, wird verwendet.
(Gelegentlich/eigentlich erwünscht.)
16-24
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Dynamische Methodenausführung
Frucht * f
Obst-Druckfür f
Zuweisung von
apfel (Obst)an f
Hier also Auswahl derMethode zur
LaufLauf-zeit.
16-25
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Virtuelle Methoden
• Dynamische Methoden, (also Methoden, die zur Laufzeit gebunden werden sollen,) werden in der Oberklasse durch virtual gekennzeichnet.
• Wenn diese Methoden beim Vererben redefiniert werden, so wird beim Aufruf für ein Objekt einer Unterklasse diejenige Methode ausgeführt, die sich aus dem Laufzeit-Typ des Objekts ergibt.
16-26
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Beispiel
class Frucht {protected:
char * dieFrucht;public:
Frucht(char *);virtual void Druck();
};
Kennzeichnung der Methode als virtual hat den Effekt, daß Aufrufe für Instanzen von Unterklassen dynamisch die entsprechende Methode suchen.
16-27
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Konsequenz
Ausgabe:
(Frucht) Frucht
(Obst) Apfel(Hfrucht) Erbse(Obst) Obst
(Südfrucht) Banane
Frucht * f = new Frucht("Frucht");
f->Druck();
f = apfel; f->Druck();
f = erbse; f->Druck();
Obst * g = new Obst("Obst");
g->Druck();
g = banane; g->Druck();
16-28
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Vorgabe EED EINI II, SS 99// überarbeitet: GD 25.4.00// demonstriert Vererbung:
// jetzt mit virtuellen Methoden//
#include <stdio.h>
class Frucht {protected:
char * dieFrucht;public:
Frucht(char *);virtual void Druck();}//virtual!
Frucht::Frucht(char * s) {dieFrucht = new char[strlen(s)];strcpy(dieFrucht, s);}
void Frucht::Druck() {cout << "(Frucht) " << dieFrucht <<
endl;}
// -------------------------------------------
class Hfrucht: public Frucht {public:
Hfrucht(char *);void Druck();
};
Hfrucht::Hfrucht(char * s) : Frucht(s) {}
void Hfrucht::Druck() {cout << "(Hfrucht) " << dieFrucht
<< endl;}
// -------------------------------------------
class Obst: public Frucht {public:
Obst(char *);void Druck();
};
Obst::Obst(char * s) : Frucht(s) {}
void Obst::Druck() {cout << "(Obst) " << dieFrucht <<
endl;}
// -------------------------------------------
class SuedFrucht: public Obst {public:
SuedFrucht(char *);void Druck();
};
SuedFrucht::SuedFrucht(char * s) : Obst(s) {}
void SuedFrucht::Druck() {cout << "(Suedfrucht) " <<
dieFrucht << endl;}
// -------------------------------------------
int main() {cout << "Zuweisungen: \n";Hfrucht * erbse = new
Hfrucht("Erbse"); erbse->Druck();Obst * apfel = new Obst("Apfel");
apfel->Druck();SuedFrucht * banane = new
SuedFrucht("Banane"); banane->Druck();cout << "\nhier: ";cout << "\nZuweisung an Zeiger auf
Frucht: \n";Frucht * f = new Frucht("Frucht");f->Druck();f = apfel; f->Druck();f = erbse; f->Druck();cout << "\nda: ";cout << "\nZuweisung an Zeiger auf
Obst: \n";Obst * g = new Obst("Obst"); g-
>Druck();g = banane; g->Druck();
cout << "fertig";}
16-29
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Fortsetzung 1 //Vererbung:jetzt mit virtuellen Methoden
Frucht::Frucht(char * s) {dieFrucht = new char[strlen(s)];strcpy(dieFrucht, s);}
void Frucht::Druck() {cout << "(Frucht) "
<< dieFrucht << endl;}
16-30
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Fortsetzung 2//Vererbung:jetzt mit virtuellen Methoden
class Hfrucht: public Frucht {public:
Hfrucht(char *);void Druck();};
Hfrucht::Hfrucht(char * s) : Frucht(s) {}
void Hfrucht::Druck() {cout << "(Hfrucht) "
<< dieFrucht << endl;}
16-31
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Fortsetzung 3//Vererbung:jetzt mit virtuellen Methoden
class Obst: public Frucht {public:
Obst(char *);void Druck();};
Obst::Obst(char * s) : Frucht(s) {}
void Obst::Druck() {cout << "(Obst) "
<< dieFrucht << endl;}
16-32
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Fortsetzung 4//Vererbung:jetzt mit virtuellen Methoden
class SuedFrucht: public Obst {public:
SuedFrucht(char *);void Druck();};
SuedFrucht::SuedFrucht(char * s) : Obst(s) {}
void SuedFrucht::Druck() {cout << "(Suedfrucht) "
<< dieFrucht << endl;}
16-33
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Fortsetzung 5//Vererbung:jetzt mit virtuellen Methoden
int main() {cout << "Zuweisungen: \n";Hfrucht * erbse =
new Hfrucht("Erbse"); erbse->Druck();Obst * apfel = new Obst("Apfel"); apfel->Druck();
SuedFrucht * banane = new SuedFrucht("Banane");banane->Druck();
cout << "\nhier: ";cout << "\nZuweisung an Zeiger auf
Frucht: \n";
16-34
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// Fruechte; Fortsetzung 6//Vererbung:jetzt mit virtuellen Methoden// Fortsetzung: main
Frucht * f = new Frucht("Frucht");f->Druck();f = apfel; f->Druck();f = erbse; f->Druck();cout << "\nda: ";cout << "\nZuweisung an Zeiger auf
Obst: \n";Obst * g = new Obst("Obst"); g->Druck();g = banane; g->Druck();
cout << "fertig";}
Fruechte_virtuell
16-35
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Ausgabe
Zuweisungen: (Umbruch geändert G.D.)
(Hfrucht) Erbse
(Obst) Apfel
(Suedfrucht) Banane
hier: Zuweisung an Zeiger auf Frucht: (Frucht) Frucht
(Obst) Apfel
(Hfrucht) Erbse
da: Zuweisung an Zeiger auf Obst: (Obst) Obst
(Suedfrucht) Banane fertig
16-36
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Achtung: Zeiger notwendig!
Ausgabe
(Obst) Obst statisch
(Obst) Banane
Obst p = Obst("Obst statisch");p.Druck();p = *banane; p.Druck();
Hier wird trotz der virtual-Vereinbarung
statisch gebunden (es wird kein Zeiger verwendet)
16-37
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Anmerkung
Eine als virtuell definierte Methode muß nicht in jeder abgeleiteten Klasse redefiniert werden. Bei der Bestimmung der konkret zu verwendenden Methode wird der Vererbungsbaum von der entsprechenden Klasse aus nach oben durch-wandert, bis eine Methode des gesuchten Namens gefunden ist.
16-38
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Beispiel
class X { public: virtual void zeige();};class Y: public X { public: void zeige();};class Z : public Y {};void X::zeige() { cout << "X"; }void Y::zeige() { cout << "Y"; }
int main() { X* zz[4] = {new X, new Z, new X, new Y}; for (int i = 0; i < 4; i++) zz[i]->zeige();return 0;
}
Ausgabe: XYXY
16-39
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Rein virtuelle Methoden
• Es kann sinnvoll sein, die Definition einer Methode zu verzögern, so daß sie erst bei der Definition der Erben definiert wird.
• Diese Methoden heißen rein virtuell.
16-40
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Beispiel
class X {public:
virtual void deute() = 0;void zeige();
};
void X::zeige() { cout << "Aufruf von deute aus: ";
deute();}
Das ist neu
16-41
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Anmerkungen
• Die Methode deute wird als virtuell deklariert.• Sie bleibt undefiniert (hat also keinen Block als Definition); das wird festgelegt durch =0 nach der Angabe der Signatur. • Erben der Klasse müssen die Definition der Methode also nachholen.
16-42
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Anmerkungen (Forts.)
• Klassen, die rein virtuelle Methoden enthalten, können nicht instanziiert werden.
– Die Objekte könnten ja die entsprechende Methode mangels Programmtextes nicht ausführen.
• Solche Klassen heißen abstrakt.
• Beachte: • Rein virtuelle Methoden können bei der Definition anderer Methoden der Klasse verwendet werden.
16-43
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Hier wird die Definition der Methode deute nachgeholt
Fortsetzung des Beispiels (1)
class Y: public X {public:
void deute();};
void Y::deute() { cout << "Y" << endl;}
Analog: class Z
16-44
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
Fortsetzung des Beispiels (2)
int main() { X* zz[2] = {new Y, new Z}; for (int i = 0; i < 2; i++)
zz[i]->zeige(); return 0;}
Ausgabe
Aufruf von deute aus: YAufruf von deute aus: Z
16-45
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// AbstraktXYZ.cpp// Vorlage EED EINI II, SS 99; // überarbeitet GD 26.4.00// Vererbung: virtuelle Methoden
#include <iostream.h>
class X {public:
virtual void deute() = 0;void zeige();};
void X::zeige() {cout << "Aufruf von deute aus: ";deute();}
class Y: public X {public:
void deute();};
void Y::deute() { cout << "Y" << endl; }
class Z : public X {public:
void deute();};
void Z::deute() { cout << "Z" << endl; }
int main() { X* zz[2] = {new Y, new Z}; for (int i = 0; i < 2; i++)
zz[i]->zeige();}
16-46
Prof. Dr. G. Dittrich08.05.2000
EINI II Kap. 16: Virtuelle Methoden
// AbstraktXYZ.cpp; Fortsetzung
class Y: public X {public: void deute();};
void Y::deute() { cout << "Y" << endl; }
class Z : public X {public: void deute();};
void Z::deute() { cout << "Z" << endl; }
int main() { X* zz[2] = {new Y, new Z}; for (int i = 0; i < 2; i++)
zz[i]->zeige(); return 0;}AbstraktXYZ