面向对象的基本继承

时间:2010-07-22 17:59:37

标签: c++ oop

考虑以下源代码。我有两个类CBar和CFoo。 CFoo继承自CBar。此源代码的输出是

Bar 
Foo 
Bar 

我在期待

Bar 
Foo 
Foo

我哪里出错了? 我在想的是因为CFoo对象有一个Speak函数可以覆盖CBar说话函数。当我从CFoo对象上的CBar函数调用Speak()函数时,将执行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 个答案:

答案 0 :(得分:3)

在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; 
} 

答案 1 :(得分:3)

Speak不是多态函数。

也就是说,因为它没有标记为virtual,所以对它的任何调用都是静态确定的。因此,在CBar中,this->Speak();将始终引用CBar::Speak

如果你使虚函数成功,将根据动态类型选择对函数的调用,而不是静态类型,以及你期望的调用。

相关问题