c ++钻石继承构造仅由基本构造函数

c++ diamond inheritance construct only by base constructor

我在构建我的女王 class 时遇到了麻烦,因为它是基础 class,我有虚拟车和象 class,以防止重复问题。现在我收到错误消息,指出 Rook 和 Bishop 是虚拟的,它没有默认构造函数。

这是我的class声明

class Piece
{
public:
  Piece(Colour c, const Position& pos);
  virtual ~Piece();
private:
  Colour piece_colour;
  Position piece_pos;
};
class Bishop: public virtual Piece
{
public:
  Bishop(Colour c, const Position& pos);
  ~Bishop();
};

class Rook: public virtual Piece
{
public:
  Rook(Colour c, const Position& pos);
  ~Rook();
};

#ifdef MSC_VER
class Queen: public virtual Piece, public Bishop, public Rook
#else
class Queen: public Bishop, public Rook
#endif
{
public:
  Queen(Colour c, const Position& pos);
  ~Queen();
};

这是我的工具

Piece::Piece(Colour c, const Position& pos)
:piece_colour{c}, piece_pos{pos}
{

}

Bishop::Bishop(Colour c, const Position& pos)
:Piece(c,pos)
{

}

Rook::Rook(Colour c, const Position& pos)
:Piece(c,pos)
{

}

Queen::Queen(Colour c, const Position& pos)
:Piece(c,pos)
{

}

请记住,当您构造一个 Queen 对象时,该对象包含一个 Rook 对象和一个 Bishop 对象。在构造 Queen 对象时也必须构造这两个对象。

由于您当前编写的代码,编译器将尝试调用默认构造函数 Bishop()Rook() 来实例化这些对象。

但是你的代码没有定义 Bishop()Rook() 构造函数 - 所以你会得到一个错误告诉你 BishopRook 类 不要'没有定义默认构造函数。

解决您的问题的一种方法是定义默认构造函数 Bishop()Rook() 以及默认构造函数 Piece()...

protected:
   Piece::Piece()   { }
   Bishop::Bishop() { }
   Rook::Rook()     { }

… 如果你这样做,你会想要使这些构造函数 protected 所以它们只能从派生的 类.

中调用

另一种方法是更改​​ Queen 构造函数以显式调用您已经定义的 BishopRook 构造函数...

Queen::Queen(Colour c, const Position& pos)
   : Bishop(c, pos), Rook(c, pos), Piece(c, pos)

如果您的 Bishop(c, pos)Rook(c, pos) 构造函数做实际工作,那么第二种方法是唯一真正的解决方案(假设实际工作取决于传递给它们的 Color 和 Position 参数)。