2014-07-25 6 views
1

저는 C++을 처음 사용하기 때문에 약간의 프로젝트를 통해 자신을 향상 시키기로했습니다. 나는 단위어떻게 가상 클래스의 벡터를 만들 수 있습니까?

#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 오류 : 확인되지 않은 외부 기호를 내 가상 메서드 "moveunit". 버그를 어떻게 해결할 수 있습니까?

+0

여기서 moveunit의 정의는 무엇입니까? 가상은 (순수하지 않다면) 메소드에 정의가 없다는 것을 의미하지 않습니다. –

+1

먼저, (스마트 한) 포인터의 벡터를 사용해야합니다. 다형성은 포인터 (또는 참조)에서만 작동합니다. '개체 썰어보기'를보세요. 둘째, Unit :: moveunit * pure virtual * (look up)을 만든다. –

+0

킹 클래스에서 정의합니다 : 이동이 유효한지 확인하는 역할을합니다. – user3875798

답변

4

당신의 문제를 해결하는 가장 쉬운 방법은 포인터 또는 스마트 포인터를 사용하고 너의 왕은 이렇게 좋아한다 :

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(...); 

그런 다음 오류가 발생합니다을, 또는 King을 인수로 취하거나 충분한 move 연산자를 제공하는 Unit에 대한 생성자를 제공하지 않는 한 적어도 문제가 발생합니다. 왜냐하면 당신이 이 아닌 유형의 객체를 unit에 할당하려고 시도하면 컴파일러 및/또는 런타임 (컴파일러의 백엔드에 따라 다름)이 얼마나 호환되는지 파악하기 때문입니다 유형이 무엇인지, 그리고 상황이 메모리에 맞지 않거나 메모리 레이아웃 문제에 대처하는 방법.

또한 읽기 포인터 대 스마트 포인터에 대한 자세한 내용은

+0

'std :: shared_ptr'로 바로 이동하는 대신에'std :: unique_ptr'을 권장합니다 ... – rubenvb

+0

@rubenvb 더 많은 제약을 가하고 더 많은 가정을하기 때문에 가장 쉬운 해결책은 아닙니다. 그의 상황. 그럼에도 불구하고 어떤 포인터 유형을 사용할 지에 대한 자세한 정보에 대한 링크가 추가되었습니다. – Domi

+0

더 많은 제한이있는 것이 일반적으로 좋은 일입니다. 왜냐하면 여러분이하는 일에 대해 생각하게 만듭니다. 'shared_ptr'은 모든 것에 맹목적으로 적용한다면 솔루션과 같은 게으른 "가비지 콜렉션"입니다. 하지만 +1, 좋은 대답. – rubenvb

1

현재 직면 한 문제는 slicing입니다. King을 벡터에 추가하면 Unit의 인스턴스로 슬라이스됩니다.

이 문제를 해결하는 한 가지 방법은 chessunitstd::shared_ptr<Unit>의 벡터로 바꾸고 힙에 단위를 할당하는 것입니다.

P. 당신이 Unit::moveunit()을 정의하지 않기 때문에, 그것은 순수 가상합니다 스토어 vector<Unit*>, vector<std::shared_ptr<Unit>> 또는 vector<std::unique_ptr<Unit>> (감사 @rubenvb) 대신 vector<Unit> 다음 추가 :

virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY) = 0; 
                    ^^^ 
관련 문제