无法修改库类时,如何让C++类D仅继承一份共同基类A?
解决菱形继承问题(无法修改第三方基类)
现有类结构如下,其中A和B属于第三方库无法修改,C和D为自定义类:
// 第三方库代码,不可修改 class A { public: float someData; float someFunc(); }; class B : public A { public: float someOtherData; float someOtherFunc(); }; // 自定义代码 class C : public A { public: float evenMoreData; float evenMoreFuncs(); }; class D : public B, public C { public: float andMoreData; float andMoreFuncs(); };
需求是让D仅继承A的一个实例,除了将B作为成员封装所有方法外,还有以下可行方案:
方案1:私有继承B+强制共享C的A实例
修改C为虚拟继承A,让D私有继承B,通过using声明明确使用C的A成员和方法,并转发B的公共接口。
// 修改C为虚拟继承A class C : virtual public A { public: float evenMoreData; float evenMoreFuncs(); }; class D : public C, private B { public: float andMoreData; float andMoreFuncs(); // 解决A的访问歧义,强制使用C的A实例 using C::someData; using C::someFunc; // 转发B的公共成员和方法 using B::someOtherData; using B::someOtherFunc; };
注意:此方案会改变B类方法的行为——原本B的方法操作自身继承的A实例,现在会改为操作C的A实例。如果业务逻辑允许共享A的状态,这个方案最简单高效。
方案2:创建虚拟继承A的B包装类
创建中间类VirtualB,它虚拟继承A并包含B的实例,调用B的方法时临时同步A的状态,确保B的方法操作共享的A实例。然后让D继承VirtualB和虚拟继承A的C。
class VirtualB : virtual public A { private: B b_instance; public: // 转发B的非A相关成员 float& someOtherData = b_instance.someOtherData; // 处理B中访问A成员的方法,临时同步状态 float someOtherFunc() { // 保存B自身的A数据,替换为共享的A数据 float temp_data = b_instance.someData; b_instance.someData = this->someData; float result = b_instance.someOtherFunc(); // 恢复B自身的A数据 b_instance.someData = temp_data; return result; } // 对B中所有访问A成员的方法做类似处理 }; // 修改C为虚拟继承A class C : virtual public A { public: float evenMoreData; float evenMoreFuncs(); }; class D : public VirtualB, public C { public: float andMoreData; float andMoreFuncs(); };
这个方案不会改变B类的原有状态,B实例自身的A数据会被临时替换为共享实例的数据,执行完方法后恢复。适合需要保留B自身A状态,但调用方法时使用共享A的场景。
内容的提问来源于stack exchange,提问作者Erwin Raupach
相关产品推荐
相关产品推荐

