C++多继承初始化疑问:如何为不同继承路径的成员赋值?
多重继承中重复基类成员的独立初始化方案
问题背景
继承结构如下:
- A、C为模板基类,均包含受保护成员
m_x和getter函数x() - E继承自A和C
- F继承自A、C和E
需求是初始化F类对象f时,实现:
- F直接继承的A的
m_x= 1 - F直接继承的C的
m_x= 2 - E继承的A的
m_x= 3 - E继承的C的
m_x= 4
当前代码因虚继承特性,输出为1、2、1、2,不符合预期,需在不改变整体继承结构的前提下解决,允许添加辅助类。
问题根源
原代码中使用了虚继承,C++虚继承的核心特性是:整个继承体系中,虚基类只会存在唯一实例。因此F直接继承的A/C,和E继承的A/C是同一个实例。F的构造函数会优先初始化虚基类,E构造函数中对虚基类的初始化会被忽略,导致所有A::x()调用都指向同一个m_x,C::x()同理。
解决方案
通过添加辅助包装类,将E继承的A/C与F直接继承的A/C分离为不同实例。具体修改如下:
修改后代码
#include <iostream> template <class T> class A { protected: T m_x; public: A(T x) : m_x(x) { } T x() { return m_x; } }; template <class T> class C { protected: T m_x; public: C(T x) : m_x(x) { } T x() { return m_x; } }; // 辅助包装类:隔离E继承的A和F直接继承的A template <class T> class A_Wrapper : public A<T> { public: using A<T>::A; // 继承基类构造函数 }; // 辅助包装类:隔离E继承的C和F直接继承的C template <class T> class C_Wrapper : public C<T> { public: using C<T>::C; // 继承基类构造函数 }; template <class T1, class T2> class E : public A_Wrapper<T1>, public C_Wrapper<T2> { public: E(T1 x_A, T2 x_C) : A_Wrapper<T1>(x_A) , C_Wrapper<T2>(x_C) { } }; template <class T1, class T2, class T3, class T4> class F : public A<T1>, public C<T2>, public E<T3, T4> { public: F(T1 x_A, T2 x_C, T3 x_E_A, T4 x_E_C) : A<T1>(x_A) , C<T2>(x_C) , E<T3, T4>(x_E_A, x_E_C) { } }; int main() { F<int, int, int, int> f(1, 2, 3, 4); std::cout << f.A::x() << '\n'; // 输出1 std::cout << f.C::x() << '\n'; // 输出2 std::cout << f.E::A_Wrapper::x() << '\n'; // 输出3 std::cout << f.E::C_Wrapper::x() << '\n'; // 输出4 return 0; }
改动说明
- 添加辅助类:
A_Wrapper和C_Wrapper分别继承A和C,作为E与A/C之间的中间层。这样E继承的是包装类,而非直接继承A/C,避免了与F直接继承的A/C共享实例。 - 调整E的继承关系:E改为继承
A_Wrapper和C_Wrapper,确保E拥有独立的A、C实例。 - 调整调用方式:主函数中访问E的A/C成员时,需要通过
A_Wrapper和C_Wrapper进行限定,以区分F直接继承的A/C实例。 - 关于缩进问题:你代码中的初始化列表缩进方式完全没问题,只要风格统一、可读性强,就不是"dumb idea"——清晰的缩进反而能提升代码维护性。
内容的提问来源于stack exchange,提问作者Patrick O'Brien
相关产品推荐
相关产品推荐

