如何判断重载的operator()是否将被赋值,以决定是否创建Matrix节点
解决方案:使用代理对象区分读写操作
核心思路是通过**代理类(Proxy Class)**替代直接返回int&,以此区分operator()调用是用于赋值(写操作)还是单纯读取(读操作),从而实现仅在赋值时创建节点的需求。
实现步骤
- 定义代理类
创建一个MatrixProxy类,保存对Matrix对象的引用以及目标行、列索引,由它负责后续的赋值或读取逻辑:
class Matrix; class MatrixProxy { private: Matrix& parent; size_t row; size_t col; public: MatrixProxy(Matrix& m, size_t r, size_t c) : parent(m), row(r), col(c) {} // 重载赋值运算符:仅当赋值时触发节点创建 MatrixProxy& operator=(int value) { parent.create_node_and_set(row, col, value); return *this; } // 重载到int的转换运算符:读取时返回值,不创建节点 operator int() const { return parent.get_value(row, col); // 内部逻辑:有节点返回值,无则返回0 } };
- 修改Matrix类的operator()
将原来返回int&的operator()改为返回MatrixProxy对象,不再直接创建节点:
class Matrix { private: // 嵌套链表的内部结构(省略具体实现) // ... // 内部方法:创建节点并设置值(原operator()中的创建逻辑移到这里) void create_node_and_set(size_t row, size_t col, int value) { // 查找或创建行、列节点,设置value的逻辑 // ... } // 内部方法:获取值,无节点返回0(不创建节点) int get_value(size_t row, size_t col) const { // 查找节点,存在则返回值,否则返回0 // ... return 0; } public: Matrix(size_t rows, size_t cols) { // 初始化逻辑,不创建任何节点 } // 返回代理对象,而非直接引用 MatrixProxy operator()(size_t row, size_t col) { return MatrixProxy(*this, row, col); } // 为const版本提供读取逻辑(可选) int operator()(size_t row, size_t col) const { return get_value(row, col); } };
- 测试逻辑验证
- 赋值操作:
matrix(4,5) = 18;会触发MatrixProxy::operator=,进而调用create_node_and_set创建节点并赋值。 - 单纯读取:
int val = matrix(4,5);或cout << matrix(4,5);会触发MatrixProxy::operator int(),调用get_value返回0,不创建节点。
关键细节说明
- 代理类的赋值运算符确保只有写操作才会触发节点创建,读操作仅返回默认值。
- 完全保留了
matrix(row, column) = x的调用格式,无需额外重载带参数的运算符。 - 可添加
const版本的operator(),处理const Matrix对象的读取场景,避免不必要的代理对象创建。
内容的提问来源于stack exchange,提问作者Not A Good Programmer
相关产品推荐
相关产品推荐

