#ifndef ARRAY2D_HPP #define ARRAY2D_HPP #include #include // 这里仅以int二维数组为例,扩展为类模板很容易 // 相比第一个版本,增加了复制构造、复制赋值、移动构造和移动赋值 class Array2D { int **arr; // 指针数组退化为二级指针 int row, col; // 二维数组的行和列 public: Array2D(int _row, int _col) : row{_row}, col{_col} { // 先申请行,再申请列 arr = new int *[row]; // 设置行 每个元素都是int * for (int i{0}; i < row; ++i) arr[i] = new int[col]; } ~Array2D() { // 注意释放的次序! for (int i{0}; i < row; ++i) delete[] arr[i]; delete[] arr; } Array2D(const Array2D &arr2d) : row{arr2d.row}, col{arr2d.col} { arr = new int *[row]; for (int i{0}; i < row; ++i) { arr[i] = new int[col]; for (int j{0}; j < col; ++j) arr[i][j] = arr2d.arr[i][j]; } } Array2D &operator=(const Array2D &arr2d) { if (this == &arr2d) return *this; // 避免自赋值 std::cout << "Copy Assign\n"; this->~Array2D(); row = arr2d.row; col = arr2d.col; arr = new int *[row]; for (int i{0}; i < row; ++i) { arr[i] = new int[col]; for (int j{0}; j < col; ++j) arr[i][j] = arr2d.arr[i][j]; } return *this; } Array2D(Array2D &&arr2d) : row{arr2d.row}, col{arr2d.col} { std::cout << "Move Construct\n"; arr = arr2d.arr; // 直接复制指针本身 arr2d.col = arr2d.row = 0; arr2d.arr = nullptr; // 被移动的对象指针可置空 } Array2D &operator=(Array2D &&arr2d) { std::cout << "Move Assign\n"; if (this == &arr2d) return *this; this->~Array2D(); // 释放已有内存 row = arr2d.row, col = arr2d.col; arr = arr2d.arr; arr2d.col = arr2d.row = 0; arr2d.arr = nullptr; return *this; } void print() { for (int i{0}; i < row; ++i) { for (int j{0}; j < col; ++j) std::cout << arr[i][j] << '\t'; std::cout << '\n'; } } int *operator[](int i) const // 重载[],允许暴露内部数据 { if (i < 0 || i >= row) throw std::out_of_range{"数组行下标越界\n"}; return arr[i]; } }; #endif