Problema con classe astratta e classi derivate

di il
6 risposte

Problema con classe astratta e classi derivate

Sto creando un progetto per un esame all'università. Ho riscontrato dei problemi.

player.cpp
Player::Player(ColorPiece c, const std::string& n) 
{
    color = c;

    setName(n);

    setPiece.resize(N_PIECES);

    //crei i pezzi del giocatore e li posiziono fuori dalla scacchiera
    setPiece[0] = new King(c);
    setPiece[1] = new Queen(c);
    setPiece[2] = new Bishop(c);
    setPiece[3] = new Bishop(c);
    setPiece[4] = new Knight(c);
    setPiece[5] = new Knight(c);
    setPiece[6] = new Rook(c);
    setPiece[7] = new Rook(c);
    setPiece[8] = new Pawn(c);
    setPiece[9] = new Pawn(c);
    setPiece[10] = new Pawn(c);
    setPiece[11] = new Pawn(c);
    setPiece[12] = new Pawn(c);
    setPiece[13] = new Pawn(c);
    setPiece[14] = new Pawn(c);
    setPiece[15] = new Pawn(c);
}
in questa parte il compilatore mi da come errore "invalid new-expression of abstract class type 'King'" ma da problemi simile per tutte le righe successive

player.h
enum ColorPiece {
    WHITE = 0,
    BLACK
};

#include "Piece.h"
#include "King.h"
#include "Knight.h"
#include "Queen.h"
#include "Bishop.h"
#include "Pawn.h"
#include "Rook.h"
#include "Tile.h"
#include <vector>
#include <string>

class Board;
class Tile;
class Piece;

class Player
{
public:

    Player(ColorPiece c, const std::string& n = "");

    ~Player();

    ColorPiece getColor() const { return color;}

    const std::string& getName() const { return name;}

    void setName(const std::string& n = "");

    void setPosPieces(std::vector<Tile*> pos);

    std::vector<Tile*> getPosPieces() const;

    const Piece& getKing() const {return *setPiece[0];}

    bool canCheckedOpposing(const Piece& king) const;
private:
    std::string name; ///< Il nome del giocatore
    ColorPiece color; ///< Il colore del giocatore e quindi dei suoi pezzi. Può essere Bianco e Nero
    const static unsigned int N_PIECES = 16;
    std::vector<Piece*> setPiece; ///< Un vettore che contiene tutti i puntatori ai pezzi del giocatore
    Board* playingBoard; ///< Puntatore alla scacchiera in cui si sta giocando
};
Per quanto riguarda le classi King, Queen etc...

knight.h
#include "Piece.h"
#include "Tile.h"
#include "Board.h"
#include <cmath>

class Knight : public Piece
{
public:

    Knight(ColorPiece c, Tile* p = 0);

    ~Knight() {}

    bool isLegalMove(const Tile& posDest, const Board& b) const;

    static std::string& getType() {
        static std::string type("Knight");
        return type;
    }
private:

};
Knight.cpp
#include "Knight.h"

Knight::Knight(ColorPiece c, Tile* p) : Piece(c, p)
{
    
}

bool Knight::isLegalMove(const Tile& posDest, const Board& b) const
{
    if ((std::abs(pos->getFile() - posDest.getFile()) == 1 && std::abs(pos->getRank() - posDest.getRank()) == 2) ||
        (std::abs(pos->getFile() - posDest.getFile()) == 2 && std::abs(pos->getRank() - posDest.getRank()) == 1))
        {
            //non serve controllare se ci siano o no pezzi d'intralcio, in quanto il cavallo sala tutti i pezzi,
            //l'unica cosa che bisogna controllare è se la casella di destinazione sia vuota o ci sia un pezzo avversario
            if (b(posDest.getFile(), posDest.getRank()).isOccupedBySamePlayer(*this))
                return false;
            
            return true;
        }

    return false;
}
le altre classi sono simile e per ugnuna mi escono 2 messaggi
"invalid use of incomplete type 'class Piece'"
"expected class-name before '{' token"

Per quanto riguarda la classe Piece:

Piece.cpp
#include "Piece.h"

Piece::Piece(ColorPiece c, Tile* p)
{
    color = c;

    pos = p;
}
Piece.h
#include "Player.h"
#include <string>

class Tile;
class Board;

class Piece
{
public:

    Piece(ColorPiece c, Tile* p = 0);

    virtual ~Piece() {}

    ColorPiece getColor() const { return color;}

    virtual bool isLegalMove(const Tile& posDest, const Board& b) = 0;

    char getSymbol() const { return symbol;}


    void movePiece(Tile* posDest) { pos = posDest;}

    Tile* getOccupingTile() const { return pos;}

protected:
    ColorPiece color;
    char symbol;
    Tile* pos;
};
Non so proprio dove sbattere la testa. Grazie in anticipo per le eventuali risposte e se vi serve qualche dettaglio in più non esitate a chiedere.

6 Risposte

  • Re: Problema con classe astratta e classi derivate

    Inizierei a a mettere il const nella funzione base
    
    virtual bool isLegalMove(const Tile& posDest, const Board& b) const = 0;
    
  • Re: Problema con classe astratta e classi derivate

    Si ho corretto quest'errore e un altro che avevo fatto nella classe BIshop e sono scomparsi tutti gli errori nel costruttore della classe Player però tutti gli altri errori sono rimasti
  • Re: Problema con classe astratta e classi derivate

    LA classe Tile come è fatta?
  • Re: Problema con classe astratta e classi derivate

    E' sicuramente un problema di dipendenze cicliche.

    Prova a spostare tutti gli includes di Player.h
    
    #include "Piece.h"
    #include "King.h"
    #include "Knight.h"
    #include "Queen.h"
    #include "Bishop.h"
    
    all'interno di Player.cpp. L'interfaccia di Player.h non dipende dalle implementazioni concrete dei pezzi.
    Non ho verificato se così funziona, ma dovrebbe essere un primo step per pulire le catene di inclusione.
    Aggiungerei anche le guardie di inclusione (include guard o pragma once)
  • Re: Problema con classe astratta e classi derivate

    E' sicuramente un problema di dipendenze cicliche.
    ho fatto come mi hai detto ed ho risolto. Grazie mille a tutti e due. Riguardo pragma once, dovrei usarlo al posto degli #ifndef #define e #endif?
  • Re: Problema con classe astratta e classi derivate

    Pragma once non è standard anche se largamente supportato, quindi no.
Devi accedere o registrarti per scrivere nel forum
6 risposte