我正在尝试使用VS-2013在c ++中实现一个纸牌游戏,我有一个“玩家”类。 “Player”类是抽象的,因为不会初始化该类的实际对象。相反,它只是继承到4个不同的玩家类(有4种不同的游戏策略) - “PlayerType1”到“PlayerType4”。
这是我的Player.h文件:
#ifndef PLAYER_H_
#define PLAYER_H_
#include <iostream>
#include "Hand.h"
using namespace std;
class Player : public Hand {
private:
const string name;
protected:
Hand myHand;
public:
string getName(); //Returns the name of the player
virtual int getShapeToAsk() = 0;
virtual int getPlayerToAsk() = 0;
virtual ~Player();
};
class PlayerType1 : public Player { //For strategy 1
PlayerType1();
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType1();
};
class PlayerType2 : public Player { //For strategy 2
PlayerType2();
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType2();
};
class PlayerType3 : public Player { //For strategy 3
private:
int myNumber, numOfPlayers, nextPlayer;
public:
PlayerType3(int myNumber, int numOfPlayers);
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType3();
};
class PlayerType4 : public Player { //For strategy 4
private:
int myNumber, numOfPlayers, nextPlayer;
public:
PlayerType4(int myNumber, int numOfPlayers);
virtual int getShapeToAsk() override;
virtual int getPlayerToAsk() override;
~PlayerType4();
};
#endif
这是我的Player.cpp文件:
#include <iostream>
#include <vector>
#include "Hand.h"
#include "Player.h"
using namespace std;
//Player functions
string Player::getName(){
return (this->name + " " + this->toString());
}
Player::~Player(){}
//PlayerType1 functions
PlayerType1::PlayerType1(){}
int PlayerType1::getShapeToAsk(){
int maxCount = 0, maxValue, currValue, count;
for (std::vector<Card*>::reverse_iterator i = this->myHand.getCards().rbegin(); i != this->myHand.getCards().rend(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().rend()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count > maxCount){
maxCount = count;
maxValue = currValue;
if (maxCount == 4) // no need to look at the rest of the hand
break;
}
}
return maxValue;
}
int PlayerType1::getPlayerToAsk(){ return -1; } //-1 means "I am a player of type 1 or 2". Game's responsibility to change later.
PlayerType1::~PlayerType1(){}
//PlayerType2 functions
PlayerType2::PlayerType2(){}
int PlayerType2::getShapeToAsk(){
int minCount = 5, minValue, currValue, count;
for (std::vector<Card*>::iterator i = this->myHand.getCards().begin(); i != this->myHand.getCards().end(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().end()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count < minCount){
minCount = count;
minValue = currValue;
if (minCount == 1) // no need to look at the rest of the hand
break;
}
}
return minValue;
}
int PlayerType2::getPlayerToAsk(){ return -1; } //-1 means "I am a player of type 1 or 2". Game's responsibility to change later.
PlayerType2::~PlayerType2(){}
//PlayerType3 functions
PlayerType3::PlayerType3(int myNumber, int numOfPlayers){
this->myNumber = myNumber;
this->numOfPlayers = numOfPlayers;
if (myNumber == 1) this->nextPlayer = 2;
else this->nextPlayer = 1;
}
int PlayerType3::getShapeToAsk(){
int maxCount = 0, maxValue, currValue, count;
for (std::vector<Card*>::reverse_iterator i = this->myHand.getCards().rbegin(); i != this->myHand.getCards().rend(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().rend()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count > maxCount){
maxCount = count;
maxValue = currValue;
if (maxCount == 4) // no need to look at the rest of the hand
break;
}
}
return maxValue;
}
int PlayerType3::getPlayerToAsk(){
int temp = this->nextPlayer;
this->nextPlayer++;
while ((this->nextPlayer == this->myNumber) || (this->nextPlayer > this->numOfPlayers)){
if (this->nextPlayer == this->myNumber) this->nextPlayer++;
if (this->nextPlayer > this->numOfPlayers) this->nextPlayer = 1;
}
return temp;
}
PlayerType3::~PlayerType3(){}
//PlayerType4 functions
PlayerType4::PlayerType4(int myNumber, int numOfPlayers){
this->myNumber = myNumber;
this->numOfPlayers = numOfPlayers;
if (myNumber == 1) this->nextPlayer = 2;
else this->nextPlayer = 1;
}
int PlayerType4::getShapeToAsk(){
int minCount = 5, minValue, currValue, count;
for (std::vector<Card*>::iterator i = this->myHand.getCards().begin(); i != this->myHand.getCards().end(); i++){
count = 1;
currValue = (**i).getValue();
for (i; (i != this->myHand.getCards().end()) && ((**i).getValue() == currValue); ++i){
count++;
}
if (count < minCount){
minCount = count;
minValue = currValue;
if (minCount == 1) // no need to look at the rest of the hand
break;
}
}
return minValue;
}
int PlayerType4::getPlayerToAsk(){
int temp = this->nextPlayer;
this->nextPlayer++;
while ((this->nextPlayer == this->myNumber) || (this->nextPlayer > this->numOfPlayers)){
if (this->nextPlayer == this->myNumber) this->nextPlayer++;
if (this->nextPlayer > this->numOfPlayers) this->nextPlayer = 1;
}
return temp;
}
PlayerType4::~PlayerType4(){}
我收到以下错误:
Error error C2512: 'Player' : no appropriate default constructor available <PATH>\player.cpp
该类型总共有4个错误,每个错误都指向PlayerType1到PlayerType4的构造函数。
当我向我的“Player”类添加一个空的默认构造函数时,它解决了问题,我得到了一个成功的构建。 但是,我不明白为什么我需要为“Player”类定义默认构造函数,因为我从不初始化该类的对象。
我还应该提到我的项目中有另一个类(“Card”类)是抽象的,只是由其他类继承(“FigureCard”和“NumericCard”),并且没有构造函数,派生类有自己的构造函数,这不会导致错误。我没有看到差异。
我搜索了其他问题,但它们都与未定义默认构造函数的情况有关,并且在代码中的其他位置尝试初始化该类。这不是我的情况,因为我没有初始化类“Player”的对象,只有4个派生类。
请帮忙! 提前谢谢。
答案 0 :(得分:1)
即使您的Player类是抽象的,您也必须定义构造函数,因为您的类具有成员。当您创建派生类(任何PlayerType)类的实例时,它将调用基类的构造函数。这就是继承的作用......
在这种情况下,让它受到保护(无论如何,公开它都是无用的,因为它是一个纯粹的虚拟类)。
答案 1 :(得分:0)
您的Player
班级有private: const string name;
个成员。看看你的Card
班级;我打赌它没有这样的成员。这就是区别。
问题是,const string name;
成员必须以某种方式初始化,因为它是private
,它必须在Player
类中初始化。 (语言规则禁止从派生类初始化类的私有成员。)因此,Player
类必须具有将初始化name
成员的构造函数。空构造函数实现了这一点。