如何实现存储不同尺寸std::array对象的std::vector容器
问题原因
你遇到的是编译期错误,并非运行时错误:基类GenericArray本身未声明data成员,也没有提供访问数组数据的通用接口,直接通过基类指针访问派生类专属成员不符合C++语法规则,因此编译阶段就会触发class GenericArray has no member named 'data'的报错。
解决方案
基于你现有的继承实现思路,只需要给基类补充通用的虚访问接口,派生类实现对应接口即可正常访问数据,同时优化内存管理避免泄漏,修改后完整代码如下:
#include <array> #include <cassert> #include <iostream> #include <vector> #include <memory> template<std::size_t N> using arr_t = std::array<unsigned char, N>; class GenericArray { public: // 基类析构必须为虚函数,避免派生类资源泄漏 virtual ~GenericArray() = default; // 声明纯虚接口:获取数据指针、数组长度 virtual unsigned char* data() = 0; virtual const unsigned char* data() const = 0; virtual std::size_t size() const = 0; }; template<std::size_t N> class MyArray : public GenericArray { public: arr_t<N> m_data; MyArray(const arr_t<N>& data): m_data(data) {} // 实现基类纯虚接口 unsigned char* data() override { return m_data.data(); } const unsigned char* data() const override { return m_data.data(); } std::size_t size() const override { return N; } }; int main(void) { // 用智能指针自动管理对象生命周期,无需手动释放 std::vector<std::unique_ptr<GenericArray>> vs; vs.emplace_back(std::make_unique<MyArray<2>>(arr_t<2>{ 'a', 'b' })); vs.emplace_back(std::make_unique<MyArray<4>>(arr_t<4>{ 'A', 'B', 'C', 'D' })); assert(vs.size() == 2); // 遍历访问第一个数组的所有元素 for (std::size_t i = 0; i < vs[0]->size(); ++i) { std::cout << vs[0]->data()[i] << "\n"; } return 0; }
补充说明
如果可以提前枚举所有可能用到的N值,也可以不用继承方案,改用std::variant<MyArray<2>, MyArray<4>, ...>存储不同大小的数组,通过std::visit访问数据即可,不需要用到虚函数。
内容的提问来源于stack exchange,提问作者Alexandru Dinu
相关产品推荐
相关产品推荐

