如何泛型处理不同大小的std::array以减少C++代码重复
用泛型基类+std::array消除相似类的代码重复
核心思路是用模板基类承载公共逻辑,把数组的编译期大小作为模板参数,让不同子类继承对应大小的基类实例,既替换了std::vector,又能最大化复用代码,还不需要多态。
先上完整代码示例:
#include <array> #include <iostream> #include <numeric> // 泛型基类:承载所有公共逻辑,模板参数指定元素类型和数组大小 template <typename T, size_t N> class BaseArrayHolder { protected: std::array<T, N> data; public: // 公共构造函数:初始化数组 BaseArrayHolder(const std::array<T, N>& init_data) : data(init_data) {} // 公共方法:打印数组内容 void print() const { std::cout << "Array content: "; for (const auto& elem : data) { std::cout << elem << " "; } std::cout << "\n"; } // 公共方法:计算数组元素总和 T sum() const { return std::accumulate(data.begin(), data.end(), T{}); } // 公共方法:获取数组大小(编译期常量) constexpr size_t size() const { return N; } }; // 子类A:继承大小为3的基类,只实现独有逻辑 class ClassA : public BaseArrayHolder<int, 3> { public: using BaseArrayHolder<int, 3>::BaseArrayHolder; // 继承基类构造函数 // 独有方法:获取第一个元素 int get_first() const { return data[0]; } }; // 子类B:继承大小为5的基类,只实现独有逻辑 class ClassB : public BaseArrayHolder<int, 5> { public: using BaseArrayHolder<int, 5>::BaseArrayHolder; // 继承基类构造函数 // 独有方法:获取最后一个元素 int get_last() const { return data.back(); } }; // 测试代码 int main() { ClassA a({1, 2, 3}); a.print(); std::cout << "Sum: " << a.sum() << "\n"; std::cout << "First element: " << a.get_first() << "\n"; ClassB b({4, 5, 6, 7, 8}); b.print(); std::cout << "Sum: " << b.sum() << "\n"; std::cout << "Last element: " << b.get_last() << "\n"; return 0; }
关键细节说明:
- 模板参数的作用:基类的
T是元素类型,N是数组大小,都是编译期确定的,完美匹配std::array的要求,完全替代std::vector的动态大小特性。 - protected成员变量:把
data设为protected,子类可以直接访问,避免冗余的getter/setter,同时保证封装性。 - 继承构造函数:用
using声明继承基类的构造函数,子类不需要重复写初始化逻辑,减少代码量。 - 无多态设计:所有方法都是非虚函数,不需要基类指针/引用,直接使用子类对象,避免虚函数表的开销,完全符合需求。
- 扩展性:如果需要支持其他元素类型(比如
double),只需要在继承时指定BaseArrayHolder<double, N>即可,基类逻辑不需要修改。
这样改造后,两个相似类的公共代码全部集中在基类,子类只保留各自独有的功能,彻底消除了代码重复,同时完全满足编译期数组大小、不使用std::vector的要求。
内容的提问来源于stack exchange,提问作者DuzaBF
相关产品推荐
相关产品推荐

