Базовое объектно-ориентированное наследование - PullRequest
2 голосов
/ 22 июля 2010

Рассмотрим следующий исходный код. У меня есть два класса CBar и CFoo. CFoo наследуется от CBar. Вывод этого исходного кода

Bar 
Foo 
Bar 

Я ожидал

Bar 
Foo 
Foo

Где я ошибся? Я думал о том, что поскольку объект CFoo имеет функцию Speak, которая переопределяет функцию разговора CBar. Когда я вызываю функцию Speak () из функции CBar для объекта CFoo, функция CFoo Speak выполняется. Но это предположение кажется неправильным.

class CBar
{
    public:
        void Speak() { 
            printf(" Bar \n"); 
        }

        void DoStuff() {
            this->Speak(); 
        }
};


class Cfoo : public CBar 
{
    public:
        void Speak() { 
            printf(" Foo \n"); 
        }

        void DoStuff() {
            CBar::DoStuff(); 
        }
};



int _tmain(int argc, _TCHAR* argv[])
{
    CBar b;
    b.Speak(); 

    Cfoo f;
    f.Speak();

    f.DoStuff(); 
    return 0;
}

Ответы [ 2 ]

3 голосов
/ 22 июля 2010

Speak не является полиморфной функцией.

То есть, поскольку он не отмечен virtual любые вызовы к нему определяются статически. Таким образом, в CBar, this->Speak(); всегда будет ссылаться на CBar::Speak.

Если вы сделаете функцию виртуальной, вызов функции будет выбран на основе динамического типа, а не статического типа, и ожидаемый вызов будет выполнен.

3 голосов
/ 22 июля 2010

В C ++ вам нужно использовать virtual для включения полиморфизма. В противном случае все, что Speak() делает в CFoo, скрывает Speak() в CBar.

class CBar 
{ 
    public: 
        virtual void Speak() {  // Note virtual keyword
            printf(" Bar \n");  
        } 

        void DoStuff() { 
            this->Speak();  
        } 
}; 


class Cfoo : public CBar  
{ 
    public: 
        void Speak() {  // Overrides the virtual method Speak()
            printf(" Foo \n");  
        } 

        void DoStuff() { // Hides CBar::DoStuff() method
            CBar::DoStuff(); 
        } 
}; 



int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CBar b; 
    b.Speak();  

    // Speak() is a virtual function, so calling Speak() on a CFoo or
    // a CBar pointer will call the most derived implementation of Speak(). 
    Cfoo f; 
    f.Speak(); 

    /* My example */
    // Since CFoo "is-a" CBar, this conversion is safe.
    CBar* bar = &f;
    // Since Speak() is a virtual function, this will call CFoo's implementation
    // of Speak(), not CBar's.
    bar->Speak();
    /* End example */

    // Because CBar::DoStuff() is hidden, this calls CFoo::DoStuff() instead.
    f.DoStuff();
    return 0; 
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...