2010-02-11 8 views
19

Widziałem kod w klasie pochodnej, ostatnio w którym programista umieścił virtual przed nadpisaniem funkcji. Czy to powszechne? Myślałem, że to było bardzo dziwne i trochę mnie zaskoczyło.Używanie 'virtual' w klasie pochodnej

Edycja: Nie pytam, co robi wirtualne, pytam, dlaczego ktoś umieściłby wirtualny w klasie pochodnej, która już przesłoniła funkcje wirtualne w swojej klasie bazowej.

EX:

class B { 
public: 
    virtual void foo(); 
    .... 
}; 

class D : public B { 
public: 
    virtual void foo(); // could have just put void foo(); 
    ... 
}; 
+4

Ja też zawsze to robię, żeby udokumentować mój kod. –

+3

To jest coś, w czym myślę, że C# jest lepszy, zmuszając klasy pochodne do użycia słowa kluczowego 'override'. – dalle

+0

To jest idealne pytanie, na które odpowiedziałem na wiele moich pytań dotyczących działania wirtualnego. Dzięki @Person –

Odpowiedz

25

virtual jest potrzebne na sterowanie ręczne funkcji (na najwyższym poziomie przynajmniej pochodne). Jest to opcjonalne, ale nieszkodliwe na niższych (bardziej pochodnych) poziomach. Jest to dobre do samodzielnego dokumentowania kodu.

+3

Dokładnie. Kompilator już wie, ale inne osoby czytające Twój kod mogą musieć śledzić wiele plików nagłówkowych, aby się tego dowiedzieć. –

3

Założę się, że znasz cel wirtualnego słowa kluczowego, ale zastanawiasz się, dlaczego nagle pojawia się on w podtypie. Jeśli się mylę, moja odpowiedź prawdopodobnie nie będzie miała większego sensu, ale zrobi to każde odniesienie w C++.

Jest całkowicie legalne umieszczenie wirtualne w klasie pochodnej. W rezultacie, jeśli masz odwołanie lub wskaźnik do tej klasy lub którejkolwiek z jej podklas, wywołania tej funkcji będą wiązały się dynamicznie w zależności od typu środowiska wykonawczego.

Mimo że zgodnie z prawem nie uważa się, że dobry projekt ma metodę nie-wirtualną w klasie bazowej i wirtualną w zastąpionej wersji.

Jednym z powodów jest to, że można mieć instancję klasy pochodnej, a następnie jeden wskaźnik do podstawy i jeden wskaźnik do wyprowadzonego i oba wskaźniki mają na celu tę instancję. Wywołanie tej samej funkcji na każdym wskaźniku będzie miało inny wynik, ponieważ wywołanie wskaźnika zadeklarowanego z klasą bazową będzie kierowało definicję w klasie bazowej.

4

Nie widzę w tym nic dziwnego. W wielu przypadkach (jeśli nie w większości przypadków) programiści tworzą deklarację funkcji nadpisującej w klasie pochodnej, kopiując ją z klasy bazowej. Nie ma sensu poświęcać dodatkowego wysiłku, aby ręcznie usunąć nadmiarowy specyfikator virtual. Co więcej, wyraźne virtual ułatwia sprawdzenie, które funkcje są wirtualne.

8

Jest to bardzo często. Poleca go wiele przewodników po stylach, np. Google. Celem jest zwiększenie czytelności kodu.

+1

Link nie działa –

+0

Nowy link tutaj http://google.github.io/styleguide/cppguide.html#Inheritance Link mówi o użyciu 'override' lub' virtual' *, ale nie obu *. –

1

Pomoże to w przypadku przyszłych wyprowadzeń. Jeśli ktoś chce czerpać klasy D i mają funkcje wirtualne, a następnie łatwo jest zrozumieć

4

Innym sposobem zwiększenia czytelności jest użyć czegoś takiego:

class B { 
public: 
    virtual void foo(); 
    .... 
}; 

class D : public B { 
public: 
    /*override*/ void foo(); 
    ... 
}; 
3

te odpowiedzi (i praktyki) są przestarzałe . Począwszy od C++ 11, należy użyć parametru override keyword, aby wyraźnie określić, że funkcja wirtualna zastępuje inną funkcję wirtualną. Twój kompilator zgłosi błąd, jeśli spróbujesz uzyskać coś, co nie jest funkcją wirtualną w klasie bazowej!

Powiązane problemy