Ein Objekt einer abgeleiteten Klasse kann einem Objekt (einer) seiner Basisklasse(n) ohne explizite Typkonvertierung zugewiesen werden:
uhr tschibo;
wecker radio;
tschibo = radio;
// OK, jeder Wecker ist eine Uhr
Andersrum gilt dies nicht:
uhr kirchturm;
wecker hahn;
hahn = kirchturm;
// NEIN, eine Uhr ist i.a. kein Wecker.
Die gleichen Reglen gelten auch für Zeiger und Referenzen:
base b; deriv d; base *pb = &d; // OK base &rb = &d; // OK deriv *pd = &b; // FEHLER deriv &rd = &b; // FEHLER
Will man auf Elemente der abgeleiteten Klasse über ein Objekt der Basisklasse oder einen Zeiger oder eine Referenz auf die Basisklasse zugreifen, braucht man eine explizite Konvertierung:
wecker w(11,30,7,15); // ein Wecker.
uhr *uhrzeiger = &w; // OK.
uhrzeiger->show();
// das ist NICHT wecker::show !!
((wecker*)uhrzeiger)->show();
// so ist's richtig!
Wie kann man im Allgemeinfall (z.B. eine Liste von uhr-Zeigern) sicherstellen, daß bei Pointerzugriff auf die richtigen Klassenelemente zugegriffen wird ???
Ein Beispiel zum Lösungsvorschlag 2.:
class uhr
{ int std;
int min;
public:
enum uhrtyp { u, w };
uhrtyp ut;
uhr(int s, int m)
: std(s), min(m), ut(u) {};
uhr() : std(0), min(0), ut(u) {};
void show();
};
class wecker : public uhr
{ public:
uhr alarmzeit;
wecker() : alarmzeit(0,0) {ut=w;}
wecker(int s, int m, int as, int am)
: uhr(s,m),
alarmzeit(as,am){ ut=w;}
};
void uhr::show()
{ cout << std << ':' << min;
if (ut == w)
{ wecker *w = (wecker*)this;
cout << " || ";
w->alarmzeit.show();
}
}
Diese Methode ist besonders bei größeren Programmen fehleranfällig: