2013-02-18 8 views
10

Mam problem z podklasowaniem i używaniem metod.Dlaczego metoda podklasy nie jest wywoływana?

Tworzę instancję klasy B i zapisuję ją jako wskaźnik do A. Ale kiedy używam wskaźnika do wywołania metody przeciążonej, wyjście jest "A", a nie "B". Czemu?

Działa to w innych językach, co robię źle?

#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

zadeklarować 'F A w()' sposób wirtualnego. aby odłożyć bingowanie w czasie wykonywania. W przeciwnym razie statyczne bingowanie dla –

+0

tak, ponieważ nie jest wirtualne –

Odpowiedz

21

f() musi być zadeklarowana virtual w klasie bazowej A:

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

innych językach, które już pracowały z może domyślnie metod wirtualnych, ale C++ nie (nie płacą za to, co don Używaj: metody wirtualne wywołują obojętność podczas wywoływania, co oznacza, że ​​są nieco wolniejsze niż zwykłe wywołania metod).

Dodając virtual, oprawa zostanie przełożona do wykonywania (zwany dynamic binding) i która f() funkcja połączenia zostanie podjęta od rodzaju wartości.

Ponieważ nie zostały zadeklarowane jako wirtualne funkcję f(), oprawa jest statyczna (w czasie kompilacji) i użyje typ zmiennej (ale nie wartość) celu określenia, które f() zadzwonić. Tak więc w twoim obecnym kodzie a->f(); dzwoni A klasa klasy f(), ponieważ a jest wskaźnikiem do klasy A.

+2

+1 za miłe wyjaśnienie :) – LihO

+1

@GrijeshChauhan dzięki za dodatkowe precyzje. – syam

6

W celu osiągnięcia właściwości polimorficzne, sposób klasy bazowej musi być virtual.

Musisz zmienić void f() na virtual void f().

2

Funkcja należy uznać virtual móc go pominąć:

#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

Gdy podklasa zapewnia implementację metody, która jest już zdefiniowana w klasie bazowej, to [** metoda przesłaniania **] (http://en.wikipedia.org/wiki/Method_overriding) nie przeciąża. – LihO