令人困惑的继承示例。构造函数被覆盖但功能不是。为什么?

时间:2014-12-22 12:46:56

标签: c++ inheritance function-overriding

您可以从下面的示例中看到我有两个类 - 一个名为Player,另一个名为Computer。 Computer类是Player的孩子。

我已经实例化了动态分配内存和新的'关键字,以便能够在不同的范围内使用它们 - 请注意计算机播放器在if语句块中实例化。

奇怪的是它编译并且玩家二是使用计算机构造函数构造的,但是当我调用player2-> takeTurn()方法时,它使用的是Player :: takeTurn()方法,而不是Computer :: takeTurn()。 。

我无法理解为什么。您可以从我使用的语言中判断出我是C ++的初学者并且更习惯于Java,所以也许我只是不了解继承在C ++中是如何工作的?

我试过的东西:

我的第一个想法是,因为我使用的是Player *指针,而不是计算机*指针(我不明白为什么会出现这个问题,但我认为我会测试)所以我尝试重铸player2的指针如下:

player2 = (Computer*) player2;

这会编译并运行,但对输出没有影响。

有谁知道为什么会发生这种情况以及如何解决这个问题?

#include <iostream>
#include <string>


using namespace std;

class Player {
private:
    string name;
    bool isTurn;
    bool isCrosses;

public:
    //constructor
    Player(string n = "") : name(n), isTurn(true), isCrosses(true) {}
    //getters
    string getName() {return name;}
    bool getIsTurn() {return isTurn;}
    bool getIsCrosses() {return isCrosses;}
    //setters
    void setName(string n) {name = n;}
    void setIsTurn(bool b) {isTurn = b;}
    void setIsCrosses(bool b) {isCrosses =b;}   
    //game functions
    int takeTurn() {
        cout << "Player " << name << " player taketurn function." << endl;      
        return 0;
    } 
};

class Computer : public Player {

public:
    Computer() : Player("Computer") {
        setIsCrosses(false);
        setIsTurn(false);
    }

    int takeTurn() {
        cout << "This is the computers taketurn function." << endl;

        return 0;
    }

};

int main() {


    //innit game variables
    bool playing = true;
    bool vsComp = true;

    Player* player1;
    Player* player2;

    player1 = new Player("aPlayer");

    if (vsComp) player2 = new Computer;




    //Gameloop  
    while (playing) {

        //draw board


        //take player input
        if (player1->getIsTurn()) {
            int cross = player1->takeTurn();    
            int naught = 0;

            player1->setIsTurn(false);
            player2->setIsTurn(true);

        } else {
            player2->takeTurn();

            player1->setIsTurn(true);
            player2->setIsTurn(false);
        }


        //update changes


    }


    //Clean up 
    delete player1;
    delete player2;

    player1 = 0;
    player2 = 0;

}

2 个答案:

答案 0 :(得分:3)

takeTurn应该是虚函数。 在基类中将虚拟放在函数定义之前:

virtual int takeTurn()

Player的析构函数也应该声明,应该是virtual

答案 1 :(得分:3)

除了上面的答案之外,我认为值得指出的是,如果您使用的是c ++ 11,您可以让编译器为您捕获此错误。

只需使用说明符override

标记您认为覆盖基类版本的任何函数 像这样:

class Computer : public Player {

...
    int takeTurn() override // override specifier added
    {
        ...
    }
...
};

这会告诉编译器“我相信这是对虚函数的覆盖 - 告诉我我是不是错了”。