class Bishop : public ChessPiece {
public:
friend class Queen;
Bishop(string colorIn, string nameIn);
//isLegalMove for bishop
//implemented this function for queen
bool isLegalBishopMove(int xSrc, int ySrc, int xDest, int yDest);
//Can move along any diagnol
virtual bool isLegalMove(int xSrc, int ySrc, int xDest, int yDest) ;
};
class Queen : public ChessPiece {
public:
//friend class Bishop;
Queen(string colorIn, string nameIn);
//friend bool Bishop::isLegalBishopMove(int xSrc, int ySrc, int xDest, int yDest);
virtual bool isLegalMove(int xSrc, int ySrc, int xDest, int yDest);
};
I want my Queen's class implementation of isLegalMove
to be able to call the function isLegalBishopMove
. How can I solve this? I tried using friend but it did not work. I am not understanding the c++ references.
I would think there is nothing wrong in free functions or public static methods. I prefer them to inheritance.
static bool Queen::isLegalMove(Position poscurr, Position posnew)
static bool Bishop::isLegalMove(Position poscurr, Position posnew)
You can't call a transverse method in a hierarchy of classes. If Queen
is not a subclass of Bishop
then trying to call a method of Bishop
class doesn't make any sense, friend
directive can't help here since you are trying to add the behavior of a class definition by including behavior from another class which is not directly related to the former.
I see two possible solutions:
static
so that you can call it freely from any context virtual
inheritance The second approach would be something like the following, but I discourage considering this since multiple inheritance has its caveats and must be fully understood before attempting its use.
class ChessPiece
{
virtual bool isLegalMove(int xSrc, int ySrc, int xDest, int yDest) = 0;
};
class Rook : public ChessPiece {
...
};
class Bishop : public ChessPiece {
...
};
class Queen : public virtual Rook, public virtual Bishop {
bool isLegalMove(int xSrc, int ySrc, int xDest, int yDest) override {
return Bishop::isLegalMove(xSrc,ySrc,xDest,yDest) || Rook::isLegalMove(xSrc, ySrc,xDest,yDest);
}
};
Mind that passing the source position of the move to isLegalMove
doesn't make much sense in an object-oriented environment, the source position should be contained in the ChessPiece
instance unless you are using the object hierarchy just to implement behavior (and not pieces state).
You can have Queen::isLegalMove
use Bishop::isLegalMove
- and presumably Castle
's - as follows:
virtual bool isLegalMove(int xSrc, int ySrc, int xDest, int yDest)
{
return Bishop().isLegalMove(xSrc, ySrc, xDest, yDest) ||
Rook().isLegalMove(xSrc, ySrc, xDest, yDest);
}
A few points:
these functions obviously (to anyone who knows even a little chess), don't need to know anything else about the Queen
piece on which they're invoked, so from that perspective they could be static
, but then they couldn't be called using virtual dispatch, which you seem to want to do and which might genuinely help keep your code simple
Board
object - to check for pieces in the way of the requested move - implies Board
is available as a global or singleton; that's discouraged in programming generally, as it makes it hard to do things like create a tree of Board
s you could reach in a fixed number of moves, to assess which move a "computer" player should make I recommend against publicly deriving Queen
from Bishop
or other pieces that it's not - try to preserve an "is a" relationship for public derivation; " Queen
is a (type of) Bishop
" is simply not true and could cause unintended trouble later as your logic for Bishop
s unintentionally affects Queen
s
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.