如何调用另一个 class 的函数?

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);
};

我希望 isLegalMove 的女王 class 实现能够调用函数 isLegalBishopMove。我该如何解决这个问题?我尝试使用朋友,但没有用。我不理解 C++ 参考资料。

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)

您可以让 Queen::isLegalMove 使用 Bishop::isLegalMove - 大概 Castle - 如下:

virtual bool isLegalMove(int xSrc, int ySrc, int xDest, int yDest)
{
    return Bishop().isLegalMove(xSrc, ySrc, xDest, yDest) ||
           Rook().isLegalMove(xSrc, ySrc, xDest, yDest);
}

几点:

  • 这些函数显然(对任何懂一点国际象棋的人来说),不需要知道关于调用它们的 Queen 棋子的任何其他信息,所以从透视它们可能 static,但随后无法使用虚拟分派调用它们,您似乎想要这样做并且可能真正有助于保持代码简单

    • 这些函数不采用 Board 对象 - 以请求移动的方式检查片段 - 意味着 Board 可作为全局或单例使用;这在编程中通常是不鼓励的,因为它很难做一些事情,比如创建一个 Board 的树,你可以在固定的移动次数中到达,以评估 "computer" 玩家应该做的移动
  • 我建议 反对 public从 Bishop 或其他不是的部分推导 Queen - 尝试为 public 推导保留 "is a" 关系; "QueenBishop" 的(类型)根本不是真的,并且以后可能会导致意想不到的麻烦,因为 Bishop 的逻辑会无意中影响Queens

您不能在 classes 的层次结构中调用横向方法。如果 Queen 不是 Bishop 的子 class 那么尝试调用 Bishop class 的方法没有任何意义,friend指令在这里无济于事,因为您试图通过包含与前者没有直接关系的另一个 class 的行为来添加 class 定义的行为。

我看到两个可能的解决方案:

  • 制作方法 static 以便您可以从任何上下文中自由调用它
  • 使用多重virtual继承

第二种方法类似于以下方法,但我不鼓励考虑这种方法,因为多重继承有其注意事项,在尝试使用之前必须充分理解。

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);
  }
};

请注意,将移动的源位置传递给 isLegalMove 在 object-oriented 环境中没有多大意义,源位置应包含在 ChessPiece 实例中,除非您正在使用对象层次结构来实现行为(而不是片段状态)。