如何创建虚拟类的向量?

时间:2014-07-25 06:53:29

标签: c++ inheritance virtual

我是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;。我该如何解决这个错误?

2 个答案:

答案 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,则编译器和/或运行时(取决于编译器的后端)将我们很难搞清楚这些类型是如何兼容的,以及如果事情不适合该怎么做?记忆以及如何处理内存布局问题。

进一步阅读

答案 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;
                                                                   ^^^