C++仅一个基类为virtual虚继承时多路径继承构造函数重复调用问题
问题原因
你遇到两次B构造的核心原因是:虚继承仅会合并所有虚继承路径下的同一基类实例,非虚继承路径的基类实例完全独立,不会参与合并。
你的代码中,D类的两条继承路径分别为:
- D → B1 → B:B1采用普通公有继承的方式继承B,该路径下的B是独立实例
- D → B2 → B:B2采用虚公有继承的方式继承B,该路径下的B是虚基类实例
两条路径的B实例没有触发合并规则,自然会调用两次B的构造函数。
构造顺序拆解
你看到的输出完全符合C++多继承构造规则:
- 最派生类D优先构造所有虚基类实例:此处B是B2的虚基类,第一次调用B构造函数,输出
B - 按继承声明顺序构造非虚基类:
- 先构造第一个基类B1:B1是普通继承B,先调用自己的基类B构造函数,输出第二个
B,再调用B1构造函数输出B1 - 再构造第二个基类B2:B的虚基类实例已经完成构造,B2无需重复构造B,直接调用B2构造函数输出
B2
- 先构造第一个基类B1:B1是普通继承B,先调用自己的基类B构造函数,输出第二个
- 最后调用D自身的构造函数,输出
D
修复方案
如果要实现你预期的仅构造一次B的效果,只需要把B1的继承方式也改为虚继承即可:
class B1: virtual public B { public: B1(){std::cout << "B1" << std::endl;} };
修改后两条继承路径均为虚继承B,D中只会保留一份B的实例,构造输出就和你的预期一致。
内容的提问来源于stack exchange,提问作者Bijan Regmi
相关产品推荐
相关产品推荐

