好久没写博客了,趁今天无聊,学习了一下怎样用github与vs连接,用git来管理代码,然后翻出来上周的面向对象的运算符重载的code,遂想着写一下博客
题目
有两个均为m行n列的矩阵A,B,求其和,赋值给C,重载“+”、“>>”、“=”、和“<<”
幸好是加法,如果是乘法直接裂开
初版
见:https://github.com/Yuzi19/Object-oriented-programming/blob/master/matrix_reload/old/0.1.cpp
此处代码运行了就会出大问题(实际上各种小问题也出过,但是在经过我的各种努力过后也能解决了)
各个重载函数
+
matrix operator+(const matrix &A, const matrix &B){ //matrix C(A.m, A.n); double **T; T = new double*[A.m]; for (int i = 0; i < A.m; i++) { T[i] = new double[A.n]; } for (int i = 0; i < A.m; i++) { for (int k = 0; k < A.n; k++) { //C.a[i][k] = A.a[i][k] + B.a[i][k]; T[i][k] = A.a[i][k] + B.a[i][k]; } } //return C; 不能像注释部分这样写,因为一旦出了函数就会调用析构函数,就会导致赋值时出错!!!(找不到指针) return matrix(T, A.m, A.n); //此处重载了构造函数}不需要看注释,注释的原因写错了,这两种写法都可以,错误不在于析构函数,而是在于没有写赋值构造函数!!(这一点下面要讲)
原理就是把两项的每一项相加
=
matrix& matrix::operator=(const matrix & A){ m = A.m; n = A.n; for (int i = 0; i < A.m; i++) { for (int k = 0; k < A.n; k++) { a[i][k] = A.a[i][k]; } } return *this; // TODO: 在此处插入 return 语句}其中的m,n都是被赋值的类的东西,最后返回的也是被赋值的类的地址
<<
ostream& operator<<(ostream& output, const matrix& A){ for (int i = 0; i < A.m; i++) { for (int k = 0; k < A.n; k++) { cout << A.a[i][k] << " "; } cout << endl; } return output; // TODO: 在此处插入 return 语句}>>
istream& operator>>(istream& input, matrix& A){
for (int i = 0; i < A.m; i++) { for (int k = 0; k < A.n; k++) { cin >> A.a[i][k]; } } return input; // TODO: 在此处插入 return 语句}十分的普通和正常,就是把输入输出改成了依次输出矩阵
构造函数和析构函数
这里的矩阵就是用二维数组来存储的,所以构造和析构要参照二级数组的方法【顺便还可以弄成动态数组】
构造
matrix::matrix(int m, int n){ this->m = m; this->n = n; a = new double*[m]; for (int i = 0; i < m; i++) { a[i] = new double[n]; }}a是一个有m个元素的数组,每一个元素都是一个double类型的指针,然后开始for,让每个元素的指针都指向一个double类型的数组,这样,一个二维数组就完成了
析构
matrix::~matrix(){ for (int i = 0; i < m; i++) { if (a[i] != NULL) { delete[]a[i]; a[i] = NULL; } } delete[]a; a = NULL;}没啥好说的,注意一下格式
老师的改版
那么,问题出在哪里呢??
原来是————没有复制构造函数!!!!
因为这里用到了数组,有数组就有指针,有指针就不能用系统自带的浅复制!!!因为浅复制把地址也给过去了,就会报错!!
复制构造函数
matrix::matrix(const matrix& M) { this->m = M.m; this->n = M.n; this->a = new double*[m]; for (int i = 0; i < m; i++) { this->a[i] = new double[n]; } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) this->a[i][j] = M.a[i][j]; }}复制构造函数实际上就是重载了一个构造函数,参数是一个类,这里就是重新创了内存空间,然后把值一个个地赋给新空间里,就不会有浅复制的错误了!!
代码详见:https://github.com/Yuzi19/Object-oriented-programming/blob/master/matrix_reload/matrix_reload.cpp
最后
跑一下程序,答案正确!!下一次不要忘记了复制构造函数哦!

