Wieso blockt die Vererbung Polymorphie?
-
Moin, moin!
Ich bin neulich über folgendes Verhalten gestolpert, nachdem ich in einer abgeleiteten Klasse eine neue Methode implementiert habe.
class A { public: virtual void foo() {std::cout << "class A::foo(void)\n";} }; class B : public A { public: void foo(int) {std::cout << "class B::foo(int)\n";} }; int main( int argc, void **argvv) { B b; A *pa = &b; b.foo(); // Fehler: er kennt nur void foo(int) pa->foo(); // kein Fehler }Wenn ich die Methode in der Klasse B auskommentiere ist alles gut. Man kann auch statt der fehlerhaften Zeile schreiben:
b.A::foo(); // so geht es!So weit so gut, die Frage ist: Warum kennt der Compiler in der abgeleiteten Klasse die Methoden der Basisklasse nicht mehr?
Ist das um "versehentliche" Aufrufe von Methoden der Basisklassen zu unterbinden, oder hat das technische Gründe?
Ich finde es recht umständlich, wenn ich bestehende Klassen erweitern muss. Entweder ich verwende einen anderen Methodennamen oder ich muss alle Methode in der Klasse wiederholen:
class B : public A { public: void foo() { A::foo(); } void foo(int) { std::cout << "class B::foo(int)\n"; } };Schön ist sowas nicht...
Was denkt ihr dazu?
LG, Dirk
-
Hallo,
dibada schrieb:
So weit so gut, die Frage ist: Warum kennt der Compiler in der abgeleiteten Klasse die Methoden der Basisklasse nicht mehr?
Weil er nur solange sucht, bis er einen passendne Namen findet.
dibada schrieb:
Entweder ich verwende einen anderen Methodennamen oder ich muss alle Methode in der Klasse wiederholen:
Oder du machst die Funktion mittels using bekannt.
-
-
using? Ich dachte das ist nur für namespaces.
Wie kann mir dabei ein using helfen?
EDIT: Habs gefunden. Das kannte ich noch nicht. Das macht ja sogar alle Methoden der Basis auf einmal bekannt.

Danke!
-
using base::foo;
-
dibada schrieb:
int main( int argc, void **argvv) { B b; A *pa = &b; b.foo(); // Fehler: er kennt nur void foo(int) pa->foo(); // kein Fehler }b.A::foo(); // so geht es!So weit so gut, die Frage ist: Warum kennt der Compiler in der abgeleiteten Klasse die Methoden der Basisklasse nicht mehr?
Kennen tut er die schon. Der "Namelookup" hört aber dann auf, wenn ein Name gefunden wurde. In der Basisklasse wird dann nicht mehr nachgeguckt. Den Effekt nennt man "Name Hiding". Das gibt's auch anders, z.B. hier:
int i = 23; void foo() { int i = 42; cout << i << endl; // 42 cout << ::i << endl; // 23 }dibada schrieb:
Ist das um "versehentliche" Aufrufe von Methoden der Basisklassen zu unterbinden, oder hat das technische Gründe?
Er ergibt sich auch dem Namelookup, was von "innen" nach "außen" bzw von "Derived" nach "Base" arbeitet und dann abbricht, wenn etwas gefunden wurde. (Dann gibt's noch ADL oder auch bekannt als Koenig-Lookup). Aber das führt jetzt zu weit. Du liest das am besten in einem Buch Deines Vertrauens nach.
dibada schrieb:
class B : public A { public: void foo() { A::foo(); } void foo(int) { std::cout << "class B::foo(int)\n"; } };Abhilfe:
class B : public A { public: using A::foo; void foo(int) { std::cout << "class B::foo(int)\n"; } };Das ist eine sogenannte Using-Deklaration.
Edit: Wow, habe ich lange gebraucht heute ...
-
[/quote]