我期待“我的游戏”打印出来,但我得到“基地” 只有在类内部使用方法时才会发生这种情况。
#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;
}
答案 0 :(得分:3)
在C ++中,您需要专门声明一个函数为virtual
:
class BaseClass {
virtual void speak () {
...
}
};
答案 1 :(得分:1)
在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";
};
};