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

C++矩阵类中如何自定义重载std::unique_ptr的[]运算符以实现列检查?

解决方案:使用代理类拦截列索引访问

核心思路是不让matrix的[]直接返回std::unique_ptr,而是返回一个代理类。这个代理类会持有行数据的指针以及矩阵的列数,当你调用代理类的[]时,就能先执行自定义列索引检查,再返回对应元素的引用。

完整代码示例

#include <memory>
#include <stdexcept>

class Matrix {
private:
    size_t rows_;
    size_t cols_;
    std::unique_ptr<std::unique_ptr<int>[]> data_; // 存储二维数据的unique_ptr

public:
    // 代理类:用于拦截列索引访问
    class RowProxy {
    private:
        int* row_data_;
        size_t cols_;

    public:
        RowProxy(int* row_data, size_t cols) : row_data_(row_data), cols_(cols) {}

        // 重载[]运算符,添加列索引检查
        int& operator[](size_t col) {
            if (col >= cols_) {
                throw std::out_of_range("Column index out of bounds");
            }
            return row_data_[col];
        }

        // 常量版本
        const int& operator[](size_t col) const {
            if (col >= cols_) {
                throw std::out_of_range("Column index out of bounds");
            }
            return row_data_[col];
        }
    };

    // 矩阵构造函数
    Matrix(size_t rows, size_t cols, int init_val) 
        : rows_(rows), cols_(cols), data_(std::make_unique<std::unique_ptr<int>[]>(rows)) {
        for (size_t i = 0; i < rows; ++i) {
            data_[i] = std::make_unique<int[]>(cols);
            for (size_t j = 0; j < cols; ++j) {
                data_[i][j] = init_val;
            }
        }
    }

    // 重载[]运算符,返回代理类
    RowProxy operator[](size_t row) {
        if (row >= rows_) {
            throw std::out_of_range("Row index out of bounds");
        }
        return RowProxy(data_[row].get(), cols_);
    }

    // 常量版本的[]重载
    const RowProxy operator[](size_t row) const {
        if (row >= rows_) {
            throw std::out_of_range("Row index out of bounds");
        }
        return RowProxy(data_[row].get(), cols_);
    }

    // 获取行数和列数的辅助方法
    size_t rows() const { return rows_; }
    size_t cols() const { return cols_; }
};

// 使用示例
#include <iostream>
int main() {
    try {
        Matrix m(5, 5, 1);
        std::cout << m[2][3] << std::endl; // 输出1
        m[4][4] = 10;
        std::cout << m[4][4] << std::endl; // 输出10
        m[5][0]; // 触发行越界异常
        // m[0][5]; // 触发列越界异常
    } catch (const std::out_of_range& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

关键细节说明

  • 代理类RowProxy:它不持有内存所有权,仅持有行数据的原始指针和列数,既避免额外内存开销,又能在访问列时执行自定义检查(比如越界判断)。
  • 矩阵的[]重载:不再返回std::unique_ptr,而是返回RowProxy对象,同时先完成行索引的合法性检查。
  • 常量支持:提供const版本的operator[],确保常量矩阵也能正确访问元素。
  • 自定义扩展性:你可以在RowProxy的operator[]中添加任意自定义逻辑,比如日志记录、调试输出或复杂权限检查等。

这种方式完全符合需求:无需继承std::unique_ptr,纯类实现,同时通过[]运算符拦截行和列的索引访问,执行自定义检查。

内容的提问来源于stack exchange,提问作者greenguy0120

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 01:51:26