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: