C++菱形继承中仅通过基类构造Queen类报错求助
解决虚继承下Queen类构造报错的问题
这个报错的根源是C++虚继承的构造函数初始化规则,咱们一步步拆解清楚:
问题本质
当使用virtual继承时,虚基类(这里是Piece)的初始化权完全属于最底层的派生类(Queen)——中间的虚派生类(Bishop和Rook)对虚基类的构造函数调用会被编译器直接忽略。但这里有个容易踩的坑:Queen继承了Bishop和Rook,这两个作为Queen的直接基类,它们的构造函数必须被调用。
你的Queen构造函数初始化列表只写了Piece(c,pos),编译器会尝试自动调用Bishop和Rook的默认构造函数,但你并没有给这两个类定义默认构造函数,所以就触发了报错。
两种解决方案
方案一:显式初始化所有直接基类(推荐)
在Queen的构造函数初始化列表中,除了初始化虚基类Piece,还要显式调用Bishop和Rook的带参构造函数。虽然Bishop和Rook里对Piece的调用会被编译器忽略,但这样能满足对直接基类构造的要求:
修改后的Queen实现代码:
Queen::Queen(Colour c, const Position& pos) : Piece(c, pos), // 负责初始化虚基类 Bishop(c, pos), // 初始化直接基类Bishop Rook(c, pos) // 初始化直接基类Rook { }
对应的类声明可以简化(现代编译器无需区分MSVC和其他编译器,虚继承的特性由Bishop/Rook继承Piece时的virtual关键字保证):
class Queen: public Bishop, public Rook { public: Queen(Colour c, const Position& pos); ~Queen(); };
方案二:给Bishop和Rook添加默认构造函数(不推荐)
如果业务逻辑允许,可以给Bishop和Rook添加默认构造函数,但要注意成员变量可能会处于未定义状态(比如piece_colour和piece_pos没有被初始化),示例:
class Bishop: public virtual Piece { public: Bishop() = default; // 默认构造函数 Bishop(Colour c, const Position& pos); ~Bishop(); }; class Rook: public virtual Piece { public: Rook() = default; // 默认构造函数 Rook(Colour c, const Position& pos); ~Rook(); };
这种方法虽然能解决报错,但不符合棋子必须有颜色和位置的业务逻辑,所以不推荐使用。
内容的提问来源于stack exchange,提问作者user3770234
相关产品推荐
相关产品推荐

