这个矩阵是当时大一下学期暑假的时候为简单的平差而写的,虽然效率不高,但是对面向对象的编程来说,还是大有裨益的。
工程文件请见:C++矩阵类实现
基本的矩阵运算(包括运算符重载)
矩阵处理
矩阵构造
矩阵操作
矩阵类的成员变量很少,主要是记录矩阵行列数的变量,以及一个存储矩阵数据的指向动态内存的指针。
矩阵类还包括静态成员变量,用于控制矩阵打印输入的格式。
c++class Matrix
{
// ---- 成员变量 ----
private:
int miRow = 0; //行数
int miCol = 0; //列数
double* mpBuf = nullptr; //存储矩阵
// ---- 静态成员变量 ----
static int iPrecise; // 控制流输出的显示精度
}
矩阵类的构造函数有多个,下面进行部分介绍
std::initializer_list
为参数的构造函数,是为了实现如同 Matlab 的矩阵构造方法设计的,这里涉及到 std::initializer_list
的使用方法c++class Matrix
{
public:
// ---- 构造函数 ----
/**
* @brief 无参数构造函数
*
* 获取一个0*0的未分配内存的空矩阵
* 不合法的计算一般返回本矩阵
*/
explicit Matrix();
/**
* @brief 构造函数
* 将double类型转化为1*1矩阵
*
* @param num 数字
*/
Matrix(double num);
/**
* @brief 构造函数
* 使用初始化列表构造矩阵
*
* @param lst 初始化列表
*/
Matrix(const MatIniLst& lst);
/**
* @brief 构造函数
* 使用初始化列表构造矩阵,列数为最多的一行的元素个数,可以以0补足其它行的元素
*
* @param lst 初始化列表(两层)
*/
Matrix(const std::initializer_list<MatIniLst>& lst);
/**
* @brief 构造函数
* 使用初始化列表构造矩阵,根据设定的列数,可以以0补足初始化列表中没有的元素
*
* @param lst 初始化列表(两层)
* @param col 矩阵列数
*/
explicit Matrix(const std::initializer_list<MatIniLst>& lst, int col);
/**
* @brief 构造函数
* 使用指针所指的数据构造矩阵,若数组长度小于需要的长度row*col,则会报错
*
* @param p double型指针,是要输入的数据
* @param row 矩阵行数
* @param col 矩阵列数
* @param count 数组长度
*/
explicit Matrix(double* p, int row, int col, int count);
}
拷贝构造(赋值)函数需要注意以下几点:
=
原始的用法,即 operator=
应当返回赋值的结果c++class Matrix
{
public:
/**
* @brief 拷贝构造函数
*
*/
Matrix(const Matrix& tmp);
/**
* @brief 运算符重载,拷贝赋值函数
* 将矩阵赋值
*
* @param tmp 待赋值的矩阵
* @return 返回赋值之后的该矩阵的引用
*/
Matrix& operator=(const Matrix& tmp);
}
关于对象移动,在 C++ primer 中有详细的介绍,下面给出我的觉得重要的几点:
noexcept
以支持与标准库交互noexcept
=
原始的用法,即 operator=
应当返回赋值的结果c++class Matrix
{
public:
/**
* @brief 移动构造函数
*
*/
Matrix(Matrix&& tmp)noexcept;
/**
* @brief 运算符重载,移动赋值函数
* 将矩阵赋值
*
* @param tmp 待赋值的矩阵
* @return 返回赋值之后的该矩阵的引用
*/
Matrix& operator=(Matrix&& tmp)noexcept;
}
析构函数没有什么特别的技术点,注意内存回收就好了
c++class Matrix
{
public:
/**
* @brief 析构函数
*/
~Matrix();
}
关于运算符重载,在 C++ primer 中也有详细的介绍。下面是我觉得需要注意的地方。
运算符重载应当与其内置版本意义相似
运算符要注意“对称”运算符与“非对称”运算符的处理。“对称”运算符应当为普通非成员函数,尤其是左侧运算对象不一定为类的对象时(这里使用的是友元函数);而“非对称”的运算符需要是成员函数,尤其是当其会改变类对象的状态时。
c++class Matrix
{
public:
/**
* @brief 运算符重载,友元函数
* 将本矩阵与所给矩阵相加求和
*
* @param lMat 左加矩阵
* @param rMat 右加矩阵
* @return 返回求和之后的该矩阵的引用
*/
friend Matrix operator+(const Matrix& lMat, const Matrix& rMat);
/**
* @brief 运算符重载
* 复合赋值+=
*
* @param tmp 要加上的矩阵
* @return 返回结果矩阵的引用
*/
Matrix& operator+=(const Matrix& tmp);
}
下标运算符通常定义两个版本:一个返回普通的引用,另一个是类的常量成员并返回常量引用。本类为了实现类的按行列的下标访问,返回类型略有不同。
c++class Matrix
{
public:
/**
* @brief 运算符重载
* 取下标
* 返回下标对应的矩阵的某一行
* 一般连续使用两个[]以获取某个指针
* 不要在类的方法中使用取下标运算符!!!
* 有两个版本,此为非常量版本
*
* @param num 下标
* @return 返回下标对应的矩阵的某一行的第一个元素的指针
*/
double* operator[](int num);
/**
* @brief 运算符重载
* 取下标
* 返回下标对应的矩阵的某一行
* 一般连续使用两个[]以获取某个指针
* 不要在类的方法中使用取下标运算符!!!
* 有两个版本,此为常量版本
*
* @param num 下标
* @return 返回下标对应的矩阵的某一行的第一个元素的指针
*/
const double* operator[](int num)const;
}
递增和递减运算符有两种版本,分别是前置和后置版本。
int
类型形参c++class Matrix
{
public:
/**
* @brief 运算符重载
* 前置递增
*
* @return 递增后的矩阵引用
*/
Matrix& operator++();
/**
* @brief 运算符重载
* 后置递增
*
* @param 区分前后置的参数
* @return 递增前的矩阵
*/
Matrix operator++(int);
}
本文作者:Zerol Acqua
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!