代码之家  ›  专栏  ›  技术社区  ›  Steven Smethurst

基本面向对象继承

  •  2
  • Steven Smethurst  · 技术社区  · 14 年前

    Bar 
    Foo 
    Bar 
    

    我在期待

    Bar 
    Foo 
    Foo
    

    我当时想的是,由于CFoo对象有一个Speak函数,它重写了CBar Speak函数。当我在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 回复  |  直到 13 年前
        1
  •  3
  •   In silico    14 年前

    在C++中,你需要使用 virtual 启用多态性。否则,所有 Speak() CFoo 他躲起来了 说话() 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; 
    } 
    
        2
  •  3
  •   GManNickG    14 年前

    Speak

    也就是说,因为它没有标记 virtual 对它的任何调用都是静态确定的。所以在里面 CBar this->Speak(); 总是指 CBar::Speak .

    如果将函数设为虚拟函数,则将根据动态类型(而不是静态类型)选择对函数的调用,并将进行所需的调用。