You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:33:37