Запутанный пример наследования. Конструктор переопределяется, но функция — нет. Зачем?

Из приведенного ниже примера видно, что у меня есть два класса — один называется Player, а другой — Computer. Компьютерный класс является потомком Player.

Я создал оба экземпляра динамически выделяемой памяти с помощью ключевого слова «new», чтобы иметь возможность использовать их в разных областях — обратите внимание, что экземпляр Computer-player создается в блоке оператора if.

Как ни странно, он компилируется, и проигрыватель два создается с помощью конструктора Computer, и все же, когда я вызываю метод player2-> takeTurn (), он использует метод Player :: takeTurn (), а не Computer :: takeTurn () …

Я не могу понять почему. По языку, который я использую, вы, вероятно, можете сказать, что я новичок в C ++ и больше привык к Java, так что, возможно, я просто не понимаю, как наследование работает в C ++?

Материал, который я попробовал:

Сначала я подумал, что это потому, что я использовал указатель Player * вместо указателя Computer * (я не понимаю, почему это было бы проблемой, но думал, что протестирую), поэтому я попытался переустановить указатель для 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;

}

0

Решение

takeTurn должна быть виртуальная функция.
В базовом классе поставьте виртуальный перед определением функции:

virtual int takeTurn()

деструктор класса Player также должны быть объявлены и должны быть virtual,

3

Другие решения

В дополнение к ответам выше, я думаю, стоит отметить, что если вы используете c ++ 11, вы можете заставить компилятор поймать эту ошибку за вас.

Просто отметьте любую функцию, которую вы считаете переопределением версии базового класса, с помощью спецификатора. override

как это:

class Computer : public Player {

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

Это приводит к тому, что компилятор сообщает: «Я считаю, что это переопределение виртуальной функции — скажите мне, если я ошибаюсь».

3

По вопросам рекламы [email protected]