如何实现MyVector的[]重载以返回底层数组片段的引用?
更优实现方案分析
你的核心思路(用代理类处理批量索引赋值)是可行的,但原方案存在继承冗余、生命周期风险、赋值运算符不规范等问题。下面是修正后的专业实现方案:
核心改进思路
放弃不必要的继承,创建独立的代理类持有原容器的引用与索引集合,重载不同类型的赋值运算符,同时完善错误处理与链式调用支持。
完整实现代码
#include <initializer_list> #include <vector> #include <stdexcept> #include <iostream> class MyVector { private: std::vector<int> data; // 若自行实现动态数组,替换为自定义数组指针+长度即可 public: // 初始化列表构造 MyVector(std::initializer_list<int> init) : data(init) {} // 单个元素索引(基础功能) int& operator[](size_t idx) { return data[idx]; } const int& operator[](size_t idx) const { return data[idx]; } // 批量索引代理类 class IndexProxy { private: MyVector& parent; std::vector<int> indices; // 存储索引副本,避免initializer_list临时对象生命周期问题 public: IndexProxy(MyVector& vec, std::initializer_list<int> ind) : parent(vec), indices(ind) {} // 给所有索引位置赋值同一个值 IndexProxy& operator=(int value) { for (int idx : indices) { check_bounds(idx); parent.data[static_cast<size_t>(idx)] = value; } return *this; // 返回自身支持链式调用 } // 按顺序给每个索引位置赋值对应列表中的值 IndexProxy& operator=(std::initializer_list<int> values) { if (indices.size() != values.size()) { throw std::invalid_argument("Indices count does not match values count"); } auto val_iter = values.begin(); for (int idx : indices) { check_bounds(idx); parent.data[static_cast<size_t>(idx)] = *val_iter++; } return *this; } // 支持读取批量索引的值(转为vector返回) operator std::vector<int>() const { std::vector<int> result; result.reserve(indices.size()); for (int idx : indices) { check_bounds(idx); result.push_back(parent.data[static_cast<size_t>(idx)]); } return result; } private: void check_bounds(int idx) const { if (static_cast<size_t>(idx) >= parent.data.size()) { throw std::out_of_range("Index out of bounds"); } } }; // 非const对象的批量索引运算符 IndexProxy operator[](std::initializer_list<int> ind) { return IndexProxy(*this, ind); } // const对象的批量索引运算符(仅支持读取) std::vector<int> operator[](std::initializer_list<int> ind) const { std::vector<int> result; result.reserve(ind.size()); for (int idx : ind) { if (static_cast<size_t>(idx) >= data.size()) { throw std::out_of_range("Index out of bounds"); } result.push_back(data[static_cast<size_t>(idx)]); } return result; } // 辅助打印函数 void print() const { for (int num : data) std::cout << num << " "; std::cout << "\n"; } };
使用示例
int main() { MyVector arr = {1, 2, 3, 4}; arr.print(); // 输出:1 2 3 4 // 批量赋值单个值 arr[{0, 2}] = 3; arr.print(); // 输出:3 2 3 4 // 批量赋值列表值 arr[{0, 2}] = {5, 6}; arr.print(); // 输出:5 2 6 4 // 链式调用 arr[{1, 3}] = 9; arr[{0, 1}] = {10, 20}; arr.print(); // 输出:10 20 6 9 // const对象读取批量值 const MyVector const_arr = {1,2,3,4}; auto vals = const_arr[{0,2}]; for (int v : vals) std::cout << v << " "; // 输出:1 3 std::cout << "\n"; return 0; }
关键优化点
- 无冗余继承:代理类仅持有原容器引用,避免继承带来的不必要开销与逻辑混乱
- 生命周期安全:用
std::vector<int>存储索引副本,规避std::initializer_list临时对象的生命周期风险 - 完善错误处理:检查索引越界、赋值列表长度匹配,抛出标准异常保证鲁棒性
- 链式调用支持:赋值运算符返回代理对象引用,支持连续批量赋值操作
- const兼容:区分const与非const版本的批量索引运算符,支持const对象的批量读取
内容的提问来源于stack exchange,提问作者DANISH ANGURAL
相关产品推荐
相关产品推荐

