C ++重写方法不起作用

时间:2014-12-04 19:09:59

标签: c++ class inheritance methods

我期待“我的游戏”打印出来,但我得到“基地” 只有在类内部使用方法时才会发生这种情况。

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

2 个答案:

答案 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";
    };
};