В моей игре TicTacToe у меня были некоторые проблемы с виртуальными функциями. Следующий код выдает ошибку в Dev C ++: «класс std :: auto_ptr» не имеет члена с именем «makeAMove».
Согласно ошибке, проблема как-то связана с функцией makeAMove, но я не вижу, что не так. Кроме того, я должен отметить, что я использую устаревшую функцию auto_ptr вместо unique_ptr, потому что очевидно, что помощь учителя в классификации моего кода не имеет компилятора, совместимого с C ++ 11.
Сейчас функции playGame и makeAMove ничего не делают, но я хочу выяснить причину ошибки, прежде чем продолжить.
Спасибо за любые предложения.
Вот соответствующий код:
Game.h (выступает в роли контроллера для игры)
#include "Player.h"#include "AIPlayer.h"#include "HumanPlayer.h"#include <memory>
class Game
{
public:
Game(unsigned int players)
{
if (players == 1)
{
player1.reset (new HumanPlayer());
player2.reset (new AIPlayer());
}
else
{
player1.reset (new HumanPlayer());
player2.reset (new HumanPlayer());
}
}
void playGame()
{
player1.makeAMove();
}
private:
std::auto_ptr<Player> player1; // pointer to a Player object (C++11 has more secure unique_ptr)
std::auto_ptr<Player> player2; // pointer to a Player object
};
Player.h (базовый класс для HumanPlayer.h и AIPlayer.h)
class Player
{
public:
virtual void makeAMove() = 0; // will accept pointer to board object as param
};
HumanPlayer.h
class HumanPlayer : public Player
{
public:
virtual void makeAMove()
{
// do some work
}
};
AIPlayer.h
#pragma once // include guard
#include "Player.h"
class AIPlayer : public Player
{
public:
virtual void makeAMove()
{
// do some work
}
};
main.cpp
#include <iostream>
#include "Game.h"
int main()
{
Game myGame(1);
myGame.playGame();
return 0;
}
Имейте в виду, что auto_ptr
действует так же, как указатель, поэтому вы должны разыменовать (либо с operator*
или же operator->
).
Интеллектуальные оболочки указателей ведут себя точно так же, как указатели. То есть, когда вы хотите использовать функции указателя (в этом случае makeAMove
), вам нужно разыменовать это:
player1->makeAMove();
В основном здесь происходит operator->
вернет Player*
позволяя вам вызвать соответствующую функцию-член Player
, с использованием operator.
даст вам доступ к auto_ptr
функции-члены (это не то, что вы хотите в этот момент в вашем коде).
Я думаю, что вы намерены сделать:
player1.get()->makeAMove();
Вам нужно позвонить makeAMove
на объекте игрока, принадлежащем auto_ptr, а не на самом auto_ptr. Хотя вы можете разыменовать auto_ptr так же, как и обычный указатель (как указали другие), благодаря перегруженным операторам.