PROJECT #0 - C++ PRIMER

160 阅读2分钟

概述

PROJECT SPECIFICATION.png

我们需要实现三个类分别为MatrixRowMatrixRowMatrixOperations,其中RowMatrix派生自Matrix

实现

Matrix

template <typename T>
class Matrix {
 protected:
  Matrix(int rows, int cols) : rows_(rows), cols_(cols), linear_(new T[rows * cols]) {}
​
  int rows_;
  int cols_;
    
  /**
   * TODO(P0): Allocate the array in the constructor.
   * TODO(P0): Deallocate the array in the destructor.
   * A flattened array containing the elements of the matrix.
   * A flattened array:这里是用一位数组来表示二维的矩阵
   */
  T *linear_;
​
 public:
​
  virtual auto GetRowCount() const -> int = 0;
  virtual auto GetColumnCount() const -> int = 0;
  virtual auto GetElement(int i, int j) const -> T = 0;
  virtual void SetElement(int i, int j, T val) = 0;
  virtual void FillFrom(const std::vector<T> &source) = 0;
​
  virtual ~Matrix() { delete[] linear_; }
};

RowMatrix

private: 
  T **data_;
​
/*
通过这里更能理解二维数组和指针的概念
data_[i]中存放的是指向数组linear_的地址的指针,再通过解引用也就是*(linear_+j)就能取到Matrix[i][j]的数据
*/
RowMatrix(int rows, int cols) : Matrix<T>(rows, cols) {
    this->data_ = new int *[rows];
    for (int i = 0; i < rows; i++) {
      //找到每一行的数组的起始地址,也就是那一行数组的头指针
      this->data_[i] = &this->linear_[i * cols];
    }
  }

这里给出c/c++申请二维数组的代码更为明显地展示出如何二维数组如何存储数据

int **arr = (int**)malloc(sizeof(int*) * row);
​
for (int i = 0; i < row; i++) 
{
    arr[i] = (int*)malloc(sizeof(int) * col);
}

瞎想

通过一维数组去理解高维数组,可以将高维数组的每一维度的信息预先规定含义

size_t类型

  void FillFrom(const std::vector<T> &source) override {
    if (source.size() != this->rows_ * this->cols_) {
      throw Exception(ExceptionType::OUT_OF_RANGE, "incorrect size");
    }
    for (int i = 0; i < source.size(); i++) {
      this->linear_[i] = source[i];
    }
  }
/*
若按此代码编译则有如下报错:
error: comparison of integer expressions of different signedness:
‘std::vector<int>::size_type’ {aka ‘long unsigned int’} and ‘int’ 
*/

通过查阅size_t被认为是无符号整数。当无符号整数与有符号整数进行比较运算时会统一视为无符号数,这样可能会发生错误。更改为:

  void FillFrom(const std::vector<T> &source) override {
    int size = static_cast<int>(source.size());
    if (size != this->rows_ * this->cols_) {
      throw Exception(ExceptionType::OUT_OF_RANGE, "incorrect size");
    }
    for (int i = 0; i < size; i++) {
      this->linear_[i] = source[i];
    }
  }

写在最后

代码本地测试是能通过的,且在代码风格检查也成功build,但在gradescope上总是Build Failed不能通过...

自己本身出发点就是边学数据库原理边学习C++,代码也是磕磕绊绊到最后完成。