0

AoA, 私はチェスのコンソール ゲームを作っています. しかし、私はポリモーフィズムで立ち往生しています, 以下はクラスと関数の定義です /* old Part //Base Class

class Piece         /*Parent class */
{
protected:
    Position* pCoord;
    std::string color;
    char symbol;
public:
    Piece(Position* Coord,std::string Color,char symbol);
    Position GetCurrentPos();
    std::string GetColor();
    void SetColor(std::string color);
    void Draw();
    virtual bool SetPos(Position* newPos){MessageBox(NULL,L"Virtual Running",L"Error",MB_OK); return true;};
    virtual ~Piece();
};

/* Inherited classes */
//Child classes
class Pawn: public Piece
{
private:
    std::vector<Position>* allowPos;
public:
    Pawn(Position* Coord,std::string Color,char symbol);
    ~Pawn();
    std::vector<Position>* GetThreatendFields();
    bool isValidMove(Position* newPos);
    bool SetPos(Position* newPos);
};
//Child classes
class Bishops: public Piece
{
private:
    std::vector<Position>* allowPos;
public:
    Bishops(Position* Coord,std::string Color,char symbol);
    ~Bishops();
    std::vector<Position>* GetThreatendFields();
    bool isValidMove(Position* newPos);
    bool SetPos(Position* newPos);
};
//Here is the implementation of child class function SetPos


   bool Pawn::SetPos(Position* newPos)
{
    bool isSet = false;

    this->pCoord = new Position();
    this->pCoord = newPos;
    isSet = true;
    MessageBox(NULL,L"Child function running",L"Yuhuu!",MB_OK);

    return isSet;
}


 class ChessBoard
{
private:
    Position ptr;       //dummy
    int SelectedPiece;
    vector<Piece> pPieceSet;
    bool isSelected;
public:
    ChessBoard();
    ~ChessBoard();
    void ShowPieces(Player *p1,Player *p2);
    void Draw();
    void MouseActivity();
    void Place(Piece& p);
};

//it just shows the peices acquired from player objects..dummy vector pointer
void ChessBoard::ShowPieces(Player* p1,Player* p2)
{
    std::vector<Piece>* vPiece = p1->GetPieces();
    for( int i=0;i<vPiece->size();i++ )
    {
        Piece& piece = vPiece->at(i);
        Place(piece);
        piece.Draw();
    }
    vPiece = p2->GetPieces();
    for( int i=0;i<vPiece->size();i++ )
    {
        Piece& piece = vPiece->at(i);
        Place(piece);
        piece.Draw();
    }
}
*/
/*new part

私はあなたが言うことをしました

Player::std::vector<Piece*> *vPieceSet;
Player::Player(int turn)
{
    this->turn = turn%2;    
    this->vPieceSet = new std::vector<Piece*>;
}
void Player::Initialize()       //Initial and final ranges for position
{
    //Initialization of pieces to their respective position
    Position pos;
    Piece *pPiece;
    if( this->turn == 0 )
    {
        this->SetName("Player 1");

        for( int i=8;i<16;i++ )
        {
            pos.SetPosition(i);
            Pawn pPawn(&pos,"blue",'P');
            pPiece = &pPawn;

            this->vPieceSet->push_back(pPiece);
        }
   //other classes same as above
}

It runs fine at initialzation function(stores all classes fine) but when use function to get the vector object

std::vector<Piece*>* Player::GetPieces()
{
    std::vector<Piece*>* tPieces = this->vPieceSet;
    return tPieces;
}

//In main.cpp
it doesnot return the vector object
        Player p1(0),p2(1);
    p1.Initialize();
    p2.Initialize();      //initialization done perfectly while debugging

    vector<Piece*> *obj = p1.GetPieces();   //returns garbage
    Piece* pObj = obj->at(0);               //garbage

    cout<<pObj->GetColor();    //  garbage

*/新規パーツ

別の問題があるようですね!

4

2 に答える 2

7

ポリモーフィズムを使用する場合、実際にやろうとしているのは、派生型のオブジェクトをインスタンス化し、基本オブジェクトへのポインターまたは参照を介してそのオブジェクトのメソッドを呼び出すことです。

class Foo
{
public:
  virtual void DoIt () { cout << "Foo"; }
};

class Bar
:
  public Foo
{
public:
  void DoIt () { cout << "Bar"; }
};

int main()
{
  Foo* foo = new Bar;
  foo->DoIt(); // OUTPUT = "Bar"
  Foo& fooRef = *foo;
  fooRef.DoIt(); // OUTPUT = "Bar"
}

これを機能させるには、オブジェクトへのポインターまたは参照を使用する必要があります。基本クラスを使用してオブジェクトのコピーを作成することはできません。コピーを作成すると、オブジェクトがスライスされます。

int main()
{ 
  Foo* foo = new Bar;
  foo->DoIt(); // OK, output = "Bar"
  Foo fooCopy = *foo;  // OOPS!  sliced Bar
  fooCopy.DoIt(); // WRONG -- output = "Foo"
}

コードでは、Pieceクラスはポリモーフィックであることを意図しており、クラスChessBoardには次のクラスがありますvector

class ChessBoard
{
private:
    vector<Piece> pPieceSet;
};

これはvectorオブジェクトPiece自体の であり、へのポインタではないためPiece、ここに入力したものはすべてスライスされます。pointers-to-pPieceSetになるように変更する必要があります。vectorPiece

vector <Piece*> pPieceSet;

にはさらに問題がInitializeあり、とにかくリファクタリングする必要があります。1 つには、もう vector1 つのPieceオブジェクトがあり、ここには 2 つの問題があります。まず、vectorポインタvectorChessBoard私はあなたのコードを徹底的に調べていないので、あなたはそれを必要とするかもしれませんが、これはエラーのようです. おそらく、ChessBoard.

あなたのInitialize方法では:

Piece *pPiece;
// ...
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
vPieceSet.push_back(*pPiece);

いくつかの問題があります。1 つ目は、 のスライスされたコピーを押し戻すことです。これは、ポインタを格納Pieceするように変更すると修正されます。vector次に、これを次のように変更した場合:

Piece *pPiece;
// ...
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
vPieceSet.push_back(pPiece); // <-- not dereferencing

ローカル (自動) 変数へのポインターを格納するため、新しい問題が発生します。これを行うのが最善です:

Piece* pPiece = new Pawn (...);
// ...
vPieceSet.push_back (pPiece);

deleteあなた のすべて を忘れ ない で くださいnew. これは、生のポインターではなく、スマート ポインターを使用することによって最もよく処理されます。C++03 ではauto_ptrがありますが、それらはvector. 代わりに、Boost などを使用するか、生のポインタを保存する必要があります。C++11 では、unique_ptr(推奨) andがありshared_ptr、これvector.

C++11 では、ここでの最善の解決策は、ベクトルを次のように宣言することです。

vector <unique_ptr <Piece> > pPieceSet;

shared_ptr...代わりに使用する必要がある場合を除きます。

于 2013-10-04T14:14:56.660 に答える