2014-12-04 157 views
0

我期待「我的遊戲」打印出來,但我得到「基地」 這隻發生在課堂內部使用方法。C++覆蓋方法不起作用

#include <iostream> 

namespace Monster { class App { 
public: 
    App(){} 
    ~App(){} 
    void run(){ 
    this->speak(); 
    } 
    void speak(){ 
    std::cout << "Base" << "\n"; 
    }; 
};}; // class/namespace 

class MyGame : public Monster::App { 
public: 
    MyGame(){} 
    ~MyGame(){} 
    void speak(){ 
    std::cout << "My Game" << "\n"; 
    }; 
}; 

int main(){ 
    MyGame *child = new MyGame; 
    child->run(); 
    return 0; 
} 
+1

化妝'speak'一個'virtual'函數,那麼 – 2014-12-04 19:11:07

+0

是的是做到了。顯然需要閱讀關於C++的更多信息 – 2014-12-04 19:13:20

+0

另外閱讀關於新的C++ 11關鍵字「覆蓋」。這非常有用。 – Silicomancer 2014-12-04 19:45:38

回答

3

在C++中需要明確聲明的功能是virtual

class BaseClass { 
    virtual void speak() { 
     ... 
    } 
}; 
0

在C++中的方法只能被重寫,如果它被標記virtual。你可以認爲virtual是「overridable」的同義詞。

關鍵字virtual必須出現在基類中。它也可能出現在覆蓋點的子類中,但不一定。

如果您使用的是支持C++ 11(你應該,如果你正在學習C++)編譯器,我建議你總是使用新override關鍵字時,你的意思重寫:

class Base { 
public: 
    virtual void speak() { 
     std::cout << "Base"; 
    } 
}; 

class Derived : public Base { 
public: 
    void speak() override { // <--- 
     std::cout << "Derived"; 
    } 
}; 

如果該方法實際上不是覆蓋,編譯器會通過提供錯誤來告訴您。

第一次閱讀並不總是很明顯,方法是一個覆蓋。例如,下面是正確的感謝返回類型的協方差:

class A {}; 
class B : public A {}; 

class Base { 
public: 
    virtual A* foo() { 
     return nullptr; 
    } 
}; 

class Derived : public Base { 
public: 
    B* foo() override { 
     return nullptr; 
    } 
}; 

這可能不是有用的,很多時候,但override清楚的情況下,有人讀它。另外,如果你的類中至少有一個虛擬方法,那麼它的析構函數也是虛擬的。這將確保需要和事物正確清理,當所有的析構函數將運行:

class App { 
public: 
    App() {} 
    virtual ~App() {} // <--- 
    void run() { 
     this->speak(); 
    } 
    virtual void speak() { 
     std::cout << "Base\n"; 
    }; 
}; 
+0

另外,從技術上講,重寫不是關鍵字,而是上下文標識符,但這並不重要。 – RudolfW 2014-12-04 19:57:19