2013-02-18 1 views
10

Ich habe Probleme mit Unterklassen und Methoden.Warum die Unterklassenmethode nicht aufgerufen wird?

Ich erstelle eine Instanz der Klasse B und speichern Sie es als Zeiger auf A. Aber wenn ich den Zeiger verwende, um die überladene Methode aufzurufen, ist die Ausgabe "A" nicht "B". Warum?

Das funktioniert in anderen Sprachen, was mache ich falsch?

#include <iostream> 
using namespace std; 

class A { 
public: 
    void f() { 
     cout << "A"; 
    } 
}; 

class B : public A { 
public: 
    void f() { 
     cout << "B"; 
    } 
}; 

int main() { 
    A *a = new B(); 
    a->f(); 
    return 0; 
} 
+3

erklären virtuelle A des 'f()' Methode. um das Binging zur Laufzeit zu verschieben. Sonst statische binging für –

+0

ja, weil es nicht virtuell ist –

Antwort

21

f() Bedürfnisse virtual in der Basisklasse A deklariert werden:

class A { 
public: 
    virtual void f() { 
     cout << "A"; 
    } 
}; 

Die anderen Sprachen, die Sie mit bereits gearbeitet, um virtuelle Methoden in Verzug gerät, aber C++ nicht (nicht zahlen für das, was Sie don t 'use: Virtuelle Methoden verursachen beim Aufruf eine Indirektion, dh sie sind etwas langsamer als normale Methodenaufrufe.

Durch virtual Zugabe wird zur Laufzeit verschoben wird verbindlich (genannt dynamic binding) und welche f() Funktionsaufruf auf dem Typ des Wertes entschieden werden.

Weil Sie nicht Funktion f() als virtuelles erklärt haben, ist die Bindung statisch (bei der Kompilierung) und den Variablentyp (aber nicht Wert) verwenden, um festzustellen, welche f() zu nennen. So in Ihrem aktuellen Code ruft a->f(); die A Klasse f(), weil a Zeiger auf die A Klasse ist.

+2

+1 für nette Erklärung :) – LihO

+1

@GrijeshChauhan danke für die zusätzlichen Präzisionen. – syam

6

Um polymorphes Verhalten zu erreichen, muss die Methode der Basisklasse virtual sein.

So in class A müssen Sie void f() zu virtual void f() ändern.

2

Die Funktion muss virtual deklariert werden können, um es außer Kraft zu setzen:

#include <iostream> 
using namespace std; 

class A { 
public: 
    virtual void f() {// Here you must define the virtual. 
     cout << "A"; 
    } 
}; 

class B : public A { 
public: 
    virtual void f() { //Here the "virtual" is optional, but a good practice 
     cout << "B"; 
    } 
}; 

int main() { 
    A *a = new B(); 
    a->f(); 
    return 0; 
} 
+1

Wenn eine Unterklasse die Implementierung einer Methode bereitstellt, die bereits in der Basisklasse definiert ist, wird [** Methode überschreiben **] (http://en.wikipedia.org/wiki/Method_overriding) nicht überladen. – LihO