LOADING

加载过慢请开启缓存 浏览器默认开启

运算符重载

2021/3/28 C++

好久没写博客了,趁今天无聊,学习了一下怎样用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

最后

跑一下程序,答案正确!!下一次不要忘记了复制构造函数哦!

cpzaxe.png