2013-07-24 11 views
5

Mam zamieszanie związane z dziedziczeniem wirtualnej właściwości metody.Wirtualne dziedziczenie funkcji

Załóżmy, że mamy 4 klasy: klasa A, klasa B, klasa C i klasa D. Klasy są dziedziczone w następujący sposób: A -> B -> C -> D, gdzie A jest klasą podstawową.

Do tego czasu jestem pewien: Rozpoczęcie deklaracji metody klasy z wirtualnym w klasie bazowej (klasa A) sprawia, że ​​metoda jest wirtualna dla wszystkich klas wywodzących się z klasy bazowej, w tym pochodnych z klasy klasy pochodne. (Metody klasy B i C określone jako wirtualne).

Zamieszanie jest tutaj. Co jeśli w klasie bazowej A nie będzie żadnego wirtualnego członka. Zamiast tego załóżmy, że klasa B deklaruje metodę wirtualną. Zakładam, że ta zmiana spowoduje, że funkcja będzie wirtualna dla wszystkich klas pochodnych, które należą do łańcucha dziedziczącego (klasy C i D). Logicznie rzecz biorąc, B dla C i D jest rodzajem ich "klasy bazowej", prawda? Czy ja się mylę?

Odpowiedz

13

Masz rację.

Myślę, że w tym przypadku najlepszym rozwiązaniem jest, aby spróbować:

#include <iostream> 

using namespace std; 

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

class B: public A { 
    public: 
     virtual void print(){ cout << "print B" << endl; }; 
}; 

class C: public B { 
    public: 
     void print(){ cout << "print C" << endl; }; 
}; 

int main() 
{ 
    A *a = new C(); 
    B *b = new C(); 

    a->print(); // will print 'print A' 
    b->print(); // will print 'print C' 

    return 1; 
} 
5

Masz całkowitą rację. Dziecko dziedziczy to, co mają jego przodkowie. Klasy podstawowe nie mogą dziedziczyć tego, co ma dziecko (np. Nowa funkcja lub zmienna). Funkcje wirtualne to po prostu funkcje, które mogą być nadpisane przez klasę potomną, jeśli ta klasa potomna zmienia implementację funkcji wirtualnej, tak że podstawowa funkcja wirtualna nie jest wywoływana.

A to klasa bazowa dla B, C, D. B jest klasą podstawową dla C, D. i C jest klasą podstawową dla D.

+0

Szybka sugestia: jeśli klasa bazowa posiada wirtualną metodę, chciałbym podkreślić resztę metod wirtualnych, które należą do klas pochodzących z słowo kluczowe wirtualne? Po prostu być bardziej ekspresyjnym. –

+0

Nie jest to konieczne. Wykonanie go raz w klasie bazowej daje wszystkim klasom podrzędnym możliwość zmiany implementacji funkcji (wszystkie są dziedziczone). – theta

+0

@RobertEagle Dodawanie 'virtual' lub' override' w klasach pochodnych nie jest konieczne *, ale chciałbym powiedzieć _yes_, dobrze jest umieścić wizualne przypomnienie semantyki funkcji tam, gdzie to możliwe. * chyba, że ​​używasz kompilatora takiego jak "g ++", który oferuje ostrzeżenia, jeśli brakuje tych kwalifikatorów, i nakazujesz traktować ostrzeżenia jako błędy. –

0

Oczywiście, że możesz to zrobić. Metoda wirtualna jest opcjonalna, aby zastąpić, więc nie ma znaczenia, że ​​zadeklarujesz ją w klasie A lub B. Jeśli nie chcesz używać tej metody w klasie A, po prostu zadeklaruj w klasie B.