简体   繁体   中英

How can I call function of another class?

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:

  • make the method static so that you can call it freely from any context
  • use multiple 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

    • that the functions don't take a 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM