C++类体系架构设计:如何让父类fun函数根据子类type值执行不同逻辑
解决方案
推荐实现方式
你需求的本质是同一种接口根据实例的属性有不同的实现,属于C++运行时多态的典型使用场景,不需要让父类依赖子类的属性,合理实现方式如下:
第一步:修改父类定义,声明虚函数
继承场景下父类需要将对外暴露的接口声明为虚函数,必须添加虚析构函数避免内存泄漏:
#include <cmath> class Parent { public: // 类构造函数 Parent() = default; // 虚析构函数,继承场景必备 virtual ~Parent() = default; // 虚成员函数,定义接口规范 virtual double fun(double x) const { // 可保留父类默认实现 return x; } };
第二步:子类继承父类,重写fun函数
将不同type对应的逻辑全部写在子类的重写方法内,父类完全不需要感知子类的type属性:
class Child : public Parent { private: int type; public: // 类构造函数 Child(int itype) : type(itype) {} // 重写父类的fun接口 double fun(double x) const override { switch(type) { case 1: return sqrt(x); case 2: return log(x); // 可自行扩展更多type分支 default: // 不符合的type走父类默认逻辑 return Parent::fun(x); } } };
调用示例
完全符合你预期的调用方式:
Child nChild1(1); nChild1.fun(5); // 返回5的平方根 Child nChild2(2); nChild2.fun(5); // 返回5的对数
架构合理性说明
你最初设想的「父类函数依赖子类属性」的设计属于业内明确不推荐的反模式,核心问题如下:
- 违反依赖倒置原则:抽象的父类属于稳定的高层模块,不应该依赖具体子类的实现细节,一旦子类修改type字段,父类逻辑也要同步调整,耦合度极高
- 破坏父类通用性:父类绑定当前子类的type属性后,无法再被其他子类继承复用
- 容易触发循环依赖:父类如果要调用子类的属性,需要提前声明子类定义,会增加编译复杂度,容易出现不可预期的编译错误
上文给出的实现方案是面向对象的常规设计,符合开闭原则,后续要新增计算逻辑只需要在子类的switch中加分支即可,完全没有上述问题。
内容的提问来源于stack exchange,提问作者lmaosome
相关产品推荐
相关产品推荐

