概述
我们需要实现三个类分别为Matrix、RowMatrix、RowMatrixOperations,其中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++,代码也是磕磕绊绊到最后完成。