2012-02-28 10 views
13
class Base 
{ 
    public: 
    virtual void func() const 
    { 
    cout<<"This is constant base "<<endl; 
    } 
}; 

class Derived : public Base 
{ 
    public: 
    virtual void func() 
    { 
    cout<<"This is non constant derived "<<endl; 
    } 
}; 


int main() 
{ 
    Base *d = new Derived(); 
    d->func(); 
    delete d; 

    return 0; 
} 

Dlaczego wydruki wyświetlają "To jest stała baza". Jednak jeśli usunę const w podstawowej wersji func(), to wypisze "To jest nie ustalone". ?funkcja wirtualna const a funkcja wirtualna niestanowiąca warunku

+0

Możliwe duplikaty http://stackoverflow.com/questions/7504300, http://stackoverflow.com/questions/3827374 i http://stackoverflow.com/questions/4152799. –

+0

możliwy duplikat [funkcji wirtualnej, która jest const w klasie bazowej, a nie const w wyprowadzonym] (http://stackoverflow.com/questions/7504300/virtual-function-that-is-const-in-the-base- class-and-not-const-in-the-deriv) –

Odpowiedz

28
virtual void func() const //in Base 
virtual void func()  //in Derived 

const część jest rzeczywistości część podpisu funkcji, co oznacza, że ​​klasa pochodna określa nowy funkcję niż unieważniając wyboru funkcji klasy bazowej. To dlatego, że ich podpisy nie pasują do siebie.

Po usunięciu const udział, wówczas ich podpis pasuje, a następnie kompilator widzi pochodzący definicję klasy func jako zastąpiona wersja funkcji klasy bazowej func, stąd pochodzi funkcja klasa nazywa jeśli typ runtime obiektem jest typ Derived. Takie zachowanie nazywa się polimorfizmem czasu wykonywania.

+0

Jestem zdezorientowany. Jeśli obie są traktowane jako 2 różne funkcje, dlaczego d-> func() wywołuje wersję pochodną, ​​ponieważ nie ma tutaj stałej stałej. – vamsi

+1

Dobrze. W rzeczywistości dość często zdarza się, że klasa definiuje dwie identyczne funkcje, jedną "const", a drugą nie. –

+2

@vamsi, definicja 'Base' zawiera tylko jedną funkcję, więc jest tą, która jest wywoływana. –

3

Nie, ponieważ virtual void func() nie zastępuje dla virtual void func() const.

4

virtual void func() ma inny podpis niż virtual void func() const. W ten sposób nie zastąpiłeś oryginalnej funkcji bazowej tylko do odczytu. W efekcie utworzyłeś nową funkcję wirtualną zamiast w programie pochodnym.

Możesz również dowiedzieć się więcej na ten temat, jeśli kiedykolwiek spróbujesz utworzyć wskaźniki do funkcji członków (PTMF), ale jest to rzadka konieczność (może to jednak być dobre dla nauki lub praktyki).

Słowo kluczowe "override" w C++ 11 jest szczególnie przydatne, aby uniknąć takich błędów. Kompilator powie, że twoja definicja "func" w wyprowadzeniu niczego nie zastąpi.

Powiązane problemy