C++错误错误C2512没有适当的默认构造函数可用

问题描述:

我想在C++中使用VS-2013实现一个纸牌游戏,并且我有一个“Player”类。 “Player”类是抽象的,因为该类的实际对象不会被初始化。相反,它只能继承4个不同的玩家类别(有4种不同的玩法) - “PlayerType1”到“PlayerType4”。C++错误错误C2512没有适当的默认构造函数可用

这是我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”类定义默认构造函数,因为我从不初始化该类的对象。

我还应该提到我的项目中有另一个类(“卡”类),它是抽象的,只是在那里被其他类继承(“图卡”和“数字卡片”),也没有构造函数,派生类有它们自己的构造函数,并且不会导致错误。我看不出有什么不同。

我搜索了其他问题,但它们都涉及未定义默认构造函数的情况,以及代码中其他地方尝试初始化该类的情况。这不是我的情况,因为我没有初始化类“Player”的对象,只有4个派生类。

请帮忙! 预先感谢您。

即使你的Player类是抽象的,你必须定义一个构造函数,因为你的类有成员。当您创建派生类(任何您的PlayerType)类的实例时,它将调用基类的构造函数。这就是继承是如何工作的...

在这种情况下,将它保护起来(因为它是一个纯虚拟类,所以它是公共的将毫无用处)。

您的Player班有一个private: const string name;成员。看看你的Card课;我敢打赌,它没有这样的成员。这是不同的。

事情是,const string name;成员必须以某种方式初始化,并且因为它是private,它必须在Player类中初始化。 (语言规则禁止从派生类中初始化类的私有成员。)因此,Player类必须具有将初始化name成员的构造函数。空的构造函数实现了这一点。

+0

谢谢!删除“const”这个词确实解决了这个问题,这也是我的“玩家”和“卡”类之间的区别。 – Gil

+0

我确实有一个问题。如果我为刚刚初始化“const string name”变量的“Player”类构造一个构造函数,并为我的派生类构造一个构造函数,我该如何去启动“名称”和其他与派生相关的事情班?假设我想让“名称”变量在“播放器”中保留一个私有的变量。 – Gil

+0

如果我正确理解你想做什么,你需要的只是从派生类中调用基础构造函数。这就是DerivedClass():BaseClass(){...'