C++模板类部分实现:消除Modifier特化代码重复方案咨询
问题场景
假设存在如下构成继承层次的两个类:
class Base { public: virtual ~Base() {} virtual int next(int x) const { return x+1; } }; class Derived: public Base { public: virtual int prev(int x) const { return x-1; } };
需要实现Modifier类模板适配两个类:
- 模板参数为
Base时,重写next()行为 - 模板参数为
Derived时,同时重写next()和prev()行为
初始实现存在明显代码重复,两个特化类中重复定义了成员变量、构造函数和next()方法;尝试多继承方案又会触发菱形继承问题,产生冗余成员。
最优实现方案
直接将公共逻辑抽离为通用基类模板,特化版本仅需要追加新增的虚函数实现即可,完全消除重复代码,同时避免菱形继承问题:
template<class T> class ModifierBase : public T { protected: const T& obj; const int k; public: ModifierBase(const T& _obj, int _k) : obj(_obj), k(_k) {} // 公共next逻辑只实现一次 int next(int x) const override { return obj.next(x) + k; } }; // 通用Modifier,默认复用ModifierBase的实现,适配Base类 template<class T> class Modifier : public ModifierBase<T> { // 直接导入基类构造函数,无需重复编写 using ModifierBase<T>::ModifierBase; }; // 仅针对Derived类特化,只需要追加prev方法的实现 template<> class Modifier<Derived> : public ModifierBase<Derived> { public: using ModifierBase<Derived>::ModifierBase; int prev(int x) const override { return obj.prev(x) - k; } };
方案优势
- 零代码重复:成员变量定义、构造逻辑、
next()实现全部维护在ModifierBase中,修改逻辑只需要改一处 - 无菱形继承问题:所有类型的继承链都是单继承结构,不存在重复的基类子对象或冗余成员:
Modifier<Base>继承链:Modifier<Base> -> ModifierBase<Base> -> BaseModifier<Derived>继承链:Modifier<Derived> -> ModifierBase<Derived> -> Derived -> Base
- 扩展成本极低:后续如果新增其他继承自
Base的派生类,只需要新增对应特化,仅编写新增虚函数的重写逻辑即可,不需要重复公共部分代码。
扩展:自动适配所有带prev方法的派生类
如果不想为每个带prev方法的派生类手动写特化,可以通过C++类型检测特性自动注入prev()重写逻辑,不需要手动维护特化:
#include <type_traits> #include <utility> // 类型trait:检测T是否存在int prev(int) const成员函数 template<class T, class = void> struct has_prev : std::false_type {}; template<class T> struct has_prev<T, std::void_t<decltype(std::declval<const T>().prev(std::declval<int>()))>> : std::is_same<decltype(std::declval<const T>().prev(std::declval<int>())), int> {}; template<class T> class ModifierBase : public T { protected: const T& obj; const int k; public: ModifierBase(const T& _obj, int _k) : obj(_obj), k(_k) {} int next(int x) const override { return obj.next(x) + k; } }; // 空mixin,T没有prev方法时不做任何处理 template<class T, bool = has_prev<T>::value> class PrevImpl {}; // T有prev方法时,自动重写prev逻辑 template<class T> class PrevImpl<T, true> : public ModifierBase<T> { public: using ModifierBase<T>::ModifierBase; int prev(int x) const override { return this->obj.prev(x) - this->k; } }; template<class T> class Modifier : public ModifierBase<T>, public PrevImpl<T> { public: using ModifierBase<T>::ModifierBase; };
该版本可以自动适配所有继承自Base、且定义了符合签名的prev方法的派生类,不需要手动添加特化。
内容的提问来源于stack exchange,提问作者user3097263
相关产品推荐
相关产品推荐

