数据结构

每一行都存储在不同的连续内存中,每一行的第一个元素的地址存储在英国数组中。

  1. class Matrix {
  2. public:
  3. int **data;
  4. size_t row;
  5. size_t col;
  6. Matrix(size_t row, size_t col) : row(row), col(col) {
  7. data = new int * [row];
  8. for (int i = 0; i < row; ++i) {
  9. data[i] = new int [col]{};
  10. }
  11. }
  12. };

矩阵的实现 - 图1

数据结构二

所有数据存储在一段连续的内存中

  1. class Matrix {
  2. public:
  3. int *data;
  4. size_t row;
  5. size_t col;
  6. Matrix(size_t row, size_t col) : row(row), col(col) {
  7. data = new int [row * col];
  8. }
  9. };

大五原则

如果一个类出现了析构函数,那么必须实现拷贝赋值函数,拷贝构造函数。C11 以后还需要实现移动构造函数,移动赋值函数。出现了析构函数说明类中有资源需要管理。

具体实现

  1. #include <iostream>
  2. #include <cassert>
  3. class Matrix {
  4. int *data;
  5. size_t row;
  6. size_t col;
  7. public:
  8. Matrix(size_t row, size_t col) : row(row), col(col) {
  9. data = new int [row * col] {};
  10. }
  11. Matrix(const Matrix &other): row(other.row), col(other.col) {
  12. data = new int [row * col];
  13. for (int i = 0; i < row * col; ++i) {
  14. data[i] = other.data[i];
  15. }
  16. }
  17. Matrix &operator = (const Matrix &other) {
  18. if (&other == this) {
  19. return *this;
  20. }
  21. if (data != nullptr) {
  22. delete []data;
  23. }
  24. this->row = other.row;
  25. this->col = other.col;
  26. data = new int [row * col];
  27. for (int i = 0; i < row * col; ++i) {
  28. data[i] = other.data[i];
  29. }
  30. return *this;
  31. }
  32. Matrix(Matrix &&other) noexcept : row(other.row), col(other.col), data(other.data) {
  33. other.row = other.col = 0;
  34. other.data = nullptr;
  35. }
  36. Matrix &operator = (Matrix &&other) noexcept {
  37. if (&other == this) {
  38. return *this;
  39. }
  40. if (data != nullptr) {
  41. delete []data;
  42. }
  43. this->row = other.row;
  44. this->col = other.col;
  45. this->data = other.data;
  46. other.row = other.col = 0;
  47. other.data = nullptr;
  48. }
  49. Matrix &operator += (const Matrix &rhs) {
  50. assert(this->row == rhs.row && this->col == rhs.col);
  51. for (int i = 0; i < row * col; ++i) {
  52. data[i] += rhs.data[0];
  53. }
  54. return *this;
  55. }
  56. Matrix operator + (const Matrix &rhs) {
  57. assert(this->row == rhs.row && this->col == rhs.col);
  58. Matrix result = *this;
  59. result += rhs;
  60. return result;
  61. }
  62. class RowProxy {
  63. Matrix & mat;
  64. size_t x;
  65. public:
  66. RowProxy(Matrix & mat, size_t x) : mat(mat), x(x) {}
  67. int &operator[] (size_t y) {
  68. assert(y >= 0 && y < mat.col);
  69. return mat.data[x*mat.col + y];
  70. }
  71. };
  72. RowProxy operator[] (size_t x) {
  73. assert(x >= 0 && x < row);
  74. return RowProxy {*this, x};
  75. }
  76. friend Matrix operator * (const Matrix &lhs, const Matrix &rhs) {
  77. assert(lhs.col == rhs.row);
  78. Matrix result(lhs.row, rhs.col);
  79. return result;
  80. }
  81. Matrix &operator *= (const Matrix &rhs) {
  82. assert(this->col == rhs.row);
  83. *this = *this * rhs;
  84. return *this;
  85. }
  86. ~Matrix() {
  87. delete []data;
  88. }
  89. };
  90. int main () {
  91. Matrix a {4, 5};
  92. Matrix b {4, 5};
  93. a[1][4] = 1;
  94. std::clog << a[1][4] ;
  95. return 0;
  96. }
  • 加入一个 RowProxy 间接层来确保第二次下标访问可以判断出是否越界。