C++ 矩阵类实现
前言
这个矩阵是当时大一下学期暑假的时候为简单的平差而写的,虽然效率不高,但是对面向对象的编程来说,还是大有裨益的。
工程文件请见:C++矩阵类实现
主要功能
基本的矩阵运算(包括运算符重载)
- 矩阵加减法
- 矩阵数乘
- 矩阵乘法
- 矩阵“除法”
- 矩阵赋值(包括复合赋值)
- 矩阵前后置自增自减
- 矩阵判等
- 矩阵广播(与数字的)
矩阵处理
- 矩阵合并
- 矩阵分割
- 矩阵打印输出
矩阵构造
- 零矩阵
- 单位矩阵
- 元素全为1的矩阵
- 构造对角矩阵
- 构造元素随机的矩阵
矩阵操作
- 矩阵转置
- 矩阵求逆
- 高斯消元法、求秩
- 行列式、伴随矩阵
- 矩阵元素下标取值
- 矩阵取对角线元素
- 化为 hessenberg 矩阵
- QR 分解
- 实对称矩阵求特征值
矩阵类技术细节
矩阵类成员变量
矩阵类的成员变量很少,主要是记录矩阵行列数的变量,以及一个存储矩阵数据的指向动态内存的指针。
矩阵类还包括静态成员变量,用于控制矩阵打印输入的格式。
class Matrix |
矩阵的构造函数
矩阵类的构造函数有多个,下面进行部分介绍
- 无参数的构造函数生成未分配内存的0*0矩阵,这个空矩阵的意义,相信大家在数据结构课的学习中能感受到的。
- 以
std::initializer_list
为参数的构造函数,是为了实现如同 Matlab 的矩阵构造方法设计的,这里涉及到std::initializer_list
的使用方法
class Matrix |
矩阵的拷贝构造(赋值)函数
拷贝构造(赋值)函数需要注意以下几点:
- 由于矩阵类中有指针和动态分配的内存,拷贝时需要用深拷贝。
- 拷贝的时候需要注意加上判断条件,拷贝的对象如果是自身,则不进行其他操作
- 在重载拷贝赋值符的时候,要保持
=
原始的用法,即operator=
应当返回赋值的结果
class Matrix |
矩阵的移动构造(赋值)函数
关于对象移动,在 C++ primer 中有详细的介绍,下面给出我的觉得重要的几点:
- 移动主要是为了从“将亡值”中取出需要的数据(这里主要是动态内存),减少了拷贝的成本。
- 移动构造(赋值)函数需要加上
noexcept
以支持与标准库交互 - 在为类的移动构造和移动赋值函数指定不抛出异常时,必须在类的头文件声明中和定义中(如果定义在类外的话)都指定
noexcept
- 移动的时候需要注意加上判断条件,移动的对象如果是自身,则不应当进行其他操作
- 在重载移动赋值符的时候,要保持
=
原始的用法,即operator=
应当返回赋值的结果
class Matrix |
矩阵的析构函数
析构函数没有什么特别的技术点,注意内存回收就好了
class Matrix |
矩阵的运算符重载
关于运算符重载,在 C++ primer 中也有详细的介绍。下面是我觉得需要注意的地方。
-
运算符重载应当与其内置版本意义相似
-
运算符要注意“对称”运算符与“非对称”运算符的处理。“对称”运算符应当为普通非成员函数,尤其是左侧运算对象不一定为类的对象时(这里使用的是友元函数);而“非对称”的运算符需要是成员函数,尤其是当其会改变类对象的状态时。
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);
} -
下标运算符通常定义两个版本:一个返回普通的引用,另一个是类的常量成员并返回常量引用。本类为了实现类的按行列的下标访问,返回类型略有不同。
class Matrix
{
public:
/**
* @brief 运算符重载
* 取下标
* 返回下标对应的矩阵的某一行
* 一般连续使用两个[]以获取某个指针
* 不要在类的方法中使用取下标运算符!!!
* 有两个版本,此为非常量版本
*
* @param num 下标
* @return 返回下标对应的矩阵的某一行的第一个元素的指针
*/
double* operator[](int num);
/**
* @brief 运算符重载
* 取下标
* 返回下标对应的矩阵的某一行
* 一般连续使用两个[]以获取某个指针
* 不要在类的方法中使用取下标运算符!!!
* 有两个版本,此为常量版本
*
* @param num 下标
* @return 返回下标对应的矩阵的某一行的第一个元素的指针
*/
const double* operator[](int num)const;
} -
递增和递减运算符有两种版本,分别是前置和后置版本。
- 前置递增递减运算符应当与内置版本意义相近,返回递增递减后对象的引用
- 前置递增递减运算符应当与内置版本意义相近,返回递增递减前对象的原值
- 区分前置和后置运算符。后置版本接受一个额外的、并不使用的
int
类型形参
class Matrix
{
public:
/**
* @brief 运算符重载
* 前置递增
*
* @return 递增后的矩阵引用
*/
Matrix& operator++();
/**
* @brief 运算符重载
* 后置递增
*
* @param 区分前后置的参数
* @return 递增前的矩阵
*/
Matrix operator++(int);
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 丘卡饮品店!
评论