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
相关产品推荐
相关产品推荐

