好久没写博客了,趁今天无聊,学习了一下怎样用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
最后
跑一下程序,答案正确!!下一次不要忘记了复制构造函数哦!