仅为子类存储成员变量创建类是否合理?多继承与方案选型探讨
关于求解器类设计的多继承与共享变量方案咨询
问题背景
我目前有若干类,每个类对应两种不同类型的求解器,初始类设计如下:
// 两个接口类 class Type1Solver { virtual void solve() = 0; }; class Type2Solver { virtual string solve(string) = 0; }; // 接口实现类 class XType1 : public Type1Solver { void solve() override; // 在.cpp中实现 }; class XType2 : public Type2Solver { string solve(string) override; // 在.cpp中实现 }; // 其他类A、B、C等也遵循同样的模式...
但XType1和XType2同属X类范畴,需要共用成员变量,因此我考虑了两种方案:
方案一:多继承共享基类
创建仅存储protected成员变量的X类,让XType1、XType2通过多继承同时继承对应Solver接口和X类:
class X { protected: unordered_map<string, string> some_data; }; // 通过多继承让X的专属求解器可以在solve()中使用X的protected变量 class XType1 : public Type1Solver, public X { void solve() override; // 在.cpp中实现 }; class XType2 : public Type2Solver, public X { string solve(string) override; // 在.cpp中实现 };
方案二:命名空间辅助结构
用命名空间存放共享变量:
namespace XHelper { unordered_map<string, string> some_data = ...; }
现咨询:该多继承用法是否合法?是否违反OOP/SOLID原则?哪种方案更合适?
解答
一、多继承用法的合法性
这种多继承写法是合法的C++语法。因为X是普通基类,Type1Solver和Type2Solver是独立的抽象接口,不存在菱形继承(多个基类继承自同一父类)的歧义问题,编译器可以正常处理。
二、是否违反OOP/SOLID原则
OOP原则层面
这种设计符合OOP的封装思想:把X相关求解器的共享状态抽离到X基类中,避免在XType1和XType2中重复定义相同变量,同时通过protected权限限制数据访问范围,只允许子类使用,保证了数据的封装性。
SOLID原则层面
逐一对照来看:
- 单一职责原则:
X类仅负责存储共享数据,职责单一;XType1和XType2分别专注于实现对应Solver接口的业务逻辑,职责清晰,符合要求。 - 开闭原则:后续新增Y、Z等其他类的求解器时,只需新增对应共享基类和求解器实现类,无需修改现有代码,符合开闭原则。
- 里氏替换原则:
XType1可以完全替换Type1Solver,XType2可以完全替换Type2Solver,不会破坏原有代码的逻辑,符合要求。 - 接口隔离原则:
Type1Solver和Type2Solver是两个独立的接口,各自提供不同的solve方法,客户端不会依赖自己不需要的接口,符合要求。 - 依赖倒置原则:
XType1和XType2依赖的是抽象的Type1Solver/Type2Solver接口,而非具体实现类,符合要求。
综上,这种多继承设计不违反OOP/SOLID原则。
三、两种方案对比与选择
方案一(多继承共享基类)的优势
- 封装性强:共享数据是类的成员,属于X相关求解器的内部状态,不会暴露给全局代码,避免了命名污染和意外修改。
- 实例隔离:每个
XType1或XType2实例都拥有独立的some_data副本(如果需要让同一X上下文的两个求解器共享数据,可以调整设计为X类包含两个求解器成员,而非让求解器继承X,核心思路依然符合封装)。 - 可扩展性好:后续可以给
X类添加共享方法,或者通过继承扩展其他共享逻辑,灵活性更高。
方案二(命名空间全局变量)的问题
- 全局状态风险:
XHelper::some_data是全局变量,所有XType1和XType2实例都会共享同一个状态,容易引发并发问题、状态污染,调试和维护难度大。 - 封装性缺失:全局变量没有访问限制,任何代码都可以修改它,违反了封装的核心思想,安全性差。
最终结论
方案一更合适。它既符合OOP和SOLID原则,保证了代码的封装性和可维护性,又能满足X类范畴下求解器共享变量的需求。
内容的提问来源于stack exchange,提问作者kohrhea
相关产品推荐
相关产品推荐

