我是C ++的新手,所以我决定开展一些小项目来改善自己。我尝试编写一个简单的国际象棋程序,其中包含类Unit,以及继承自Unit
的类King #include <list>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stdlib.h> /* abs */
using namespace std;
// Each unit class represent a chess unit
class Unit{
protected:
int currentX;
int currentY;
string side;
public:
Unit();
Unit(string sideplay, int Xpos,int Ypos)
{
currentX=Xpos; currentY= Ypos;side=sideplay;
}
int getX()
{
return currentX;
}
int getY()
{
return currentY;
}
string getside()
{
return side;
}
void setpos(int newX,int newY) //set new position
{
currentX=newX;
currentY=newY;
}
bool validmove(vector<Unit> unitlist ,string sidepick,int Xpos,int Ypos)
{ int i=0;
while(i != 3)
{ int X=unitlist[i].getX();
int Y=unitlist[i].getY();
string sidetemp= unitlist[i].getside();
if ((X==Xpos)&&(Y==Ypos)&&(sidetemp==sidepick))
{
return false;
}
else if ((X==Xpos)&&(Y==Ypos)&&(sidetemp!=sidepick))
{ //unitlist[i]=NULL;
return true;
}
i++;
}
return true;
}
virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY);
};
class King: public Unit{
public:
King(string sideplay, int Xpos,int Ypos):Unit(sideplay,Xpos,Ypos)
{}
void moveunit(vector<Unit> unitlist ,int nextX,int nextY){
int diffX=abs(nextX-currentX);
int diffY=abs(nextY-currentY);
if ((diffX==1)||(diffY==1))
{ if (validmove(unitlist,side,nextX,nextY))
{
setpos(nextX,nextY);}
}
}
};
这是我的主要内容:
int main()
{
vector<Unit> chessunit;
chessunit.push_back(King("white",3,1));
chessunit.push_back(King("black",3,2));
chessunit.push_back(King("white",4,1));
if (chessunit[0].validmove(chessunit,"white",3,2))
{
cout<<"hehe"<<endl;
}
chessunit[0].moveunit(chessunit,3,2);
int k= chessunit[0].getY();
cout<<k<<endl;
return 0;
}
我一直收到LNK 2001错误:我的虚拟方法未解决的外部符号&#34; moveunit&#34;。我该如何解决这个错误?
答案 0 :(得分:4)
解决问题的最简单方法是使用指针或智能指针:存储vector<Unit*>
,vector<std::shared_ptr<Unit>>
或vector<std::unique_ptr<Unit>>
(感谢@rubenvb)而不是vector<Unit>
然后添加你的国王是这样的:
myVector.push_back(new King...); // or
myVector.push_back(std::shared_ptr<King>(new King...)); // or
myVector.push_back(std::unique_ptr<King>(new King...));
<强>为什么吗
如果你分配了一个虚拟类的对象(例如Unit unit
),并且想要为该类分配一个实现的对象,例如:
Unit unit;
unit = King(...);
然后你会收到一个错误,或者至少遇到麻烦,除非你提供Unit
的构造函数,它以King
为参数或提供足够的move
运算符。这是因为如果您尝试将类型不是Unit
的对象分配给unit
,则编译器和/或运行时(取决于编译器的后端)将我们很难搞清楚这些类型是如何兼容的,以及如果事情不适合该怎么做?记忆以及如何处理内存布局问题。
进一步阅读
shared_ptr
with STL collections 答案 1 :(得分:1)
您现在面临的问题归因于slicing:向向量添加King
时,会将其切片为Unit
的实例。
解决此问题的一种方法是将chessunit
转换为std::shared_ptr<Unit>
的向量,并在堆上分配单位。
P.S。由于您没有定义Unit::moveunit()
,因此请将其设为纯虚拟:
virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY) = 0;
^^^