C++中二维float数组的移动语义正确实现方法咨询
正确实现float二维数组的移动语义
你的代码存在几个核心问题,直接导致了移动后对象指针变为nullptr:
- 指针逻辑错误:你先将
rhs.matrix赋值给this->matrix,此时两者指向同一个指针数组。后续循环里的matrix[i] = rhs.matrix[i]属于无意义的自我赋值,而把rhs.matrix[i]置空的操作,会同时让this->matrix[i]也变成空指针,最后再把rhs.matrix置空,自然this->matrix也会变为nullptr。 - 未转移行列信息:移动操作不仅要转移数组指针,还要同步接管
rhs的rows和cols,否则原对象的行列数与新接管的数组不匹配,后续析构或操作必然出错。
修正后的完整实现
struct Matrix { // 移动赋值运算符 Matrix& operator=(Matrix&& rhs) noexcept { // 自我赋值检查(移动语义中极少遇到,但保留也无问题) if (this == &rhs) { return *this; } // 1. 释放当前对象已有的资源 for (size_t i = 0; i < rows; ++i) { delete[] matrix[i]; } delete[] matrix; // 2. 接管右值对象的资源所有权 matrix = rhs.matrix; rows = rhs.rows; cols = rhs.cols; // 3. 将右值对象置为安全空状态,避免其析构时释放我们刚接管的资源 rhs.matrix = nullptr; rhs.rows = 0; rhs.cols = 0; return *this; } ~Matrix() { // 空指针判断避免无效释放与循环越界 if (matrix != nullptr) { for (size_t i = 0; i < rows; ++i) { delete[] matrix[i]; } delete[] matrix; } } // 配套移动构造函数,完善移动语义 Matrix(Matrix&& rhs) noexcept : rows(rhs.rows), cols(rhs.cols), matrix(rhs.matrix) { rhs.matrix = nullptr; rhs.rows = 0; rhs.cols = 0; } // 禁用拷贝构造与拷贝赋值,避免浅拷贝导致的重复释放问题 Matrix(const Matrix&) = delete; Matrix& operator=(const Matrix&) = delete; // 默认初始化空状态 int rows = 0; int cols = 0; float** matrix = nullptr; };
关键逻辑说明
- 资源释放:先释放当前对象的每一行数组,再释放指针数组,确保无内存泄漏。
- 所有权转移:直接接管
rhs的指针、行列数,这是移动语义的核心——不需要复制任何数据,仅转移内存所有权。 - 重置右值对象:将
rhs的指针置空、行列数设为0,确保其析构时不会释放已转移的资源,同时让rhs处于安全的可析构状态。
内容的提问来源于stack exchange,提问作者randomuser228
相关产品推荐
相关产品推荐

