C++派生类复用基类操作仅返回类型不同的避重实现方案
方案可行性说明
你提到的C++20受约束模板方案是完全可行的,只要满足以下前提即可正常运行:
- 所有派生类都公开继承
Base - 派生类的对应运算符(如
*=、*)已正确实现 - 派生类支持正常的拷贝/移动构造,保证存入
std::vector时不会出现数据截断
这种方案的优势是不需要修改Base类的非模板属性,仅对需要复用的操作做模板化改造,不需要派生类重复声明或实现任何继承来的操作,调用时传入派生类实例就会自动返回对应派生类类型的结果。
更通用的优化方案:CRTP(奇异递归模板模式)
如果你需要兼容C++20之前的标准,或者想要更清晰的类结构,CRTP是比直接在Base中写约束模板更优的选择,它可以完全消除派生类中的重复代码,连运算符重载的声明都不需要写:
// 基类改为模板类,模板参数为派生类类型 template <typename DerivedT> class Base { private: std::vector<unsigned int> _arr; public: // 运算符重载直接返回派生类引用 DerivedT& operator *= (const DerivedT& rhs) { // 原有Base::operator*=的逻辑不变 return *static_cast<DerivedT*>(this); } friend DerivedT operator *(DerivedT lhs, const DerivedT& rhs) { lhs *= rhs; return lhs; } // 自定义操作直接返回派生类的vector std::vector<DerivedT> myoperation(const DerivedT& rhs) { std::vector<DerivedT> ret{}; ret.push_back(rhs * rhs); return ret; } }; // 派生类继承时传入自身作为模板参数 class Derived : public Base<Derived> { private: std::vector<int> _arr_derived; public: // 仅需要实现派生类独有的操作即可 Derived& my_derived_operation(const Derived& rhs) { // 自定义逻辑 return *this; } };
使用CRTP后,你可以直接调用Derived实例的*=、*、myoperation方法,返回值自动为Derived或std::vector<Derived>,不需要在派生类中写任何重复代码。
两种方案对比
| 方案 | 适用标准 | 优势 | 劣势 |
|---|---|---|---|
| C++20受约束模板 | C++20及以上 | Base不需要是模板类,不会产生多份基类实例 | 依赖C++20特性 |
| CRTP | C++11及以上 | 兼容性好,类结构清晰,完全消除重复代码 | 每个派生类会实例化一份对应基类模板,编译开销可忽略 |
内容的提问来源于stack exchange,提问作者Reimundo Heluani
相关产品推荐
相关产品推荐

