Сумма Матриц

Тема в разделе "C/C++/C#", создана пользователем BadWolf, 19 янв 2012.

  1. BadWolf

    BadWolf Гость

    Задача: Составить программу, которая вычисляет сумму матриц. Перегрузить операторы "+" и "=".

    Код (C++):
    #include<iostream>
    #include<time.h>

    using namespace std;

    class Matrix
    {
    int n; //strioki
    int m; //stolbiki
    int **M; //sobstvenno matrix
    public:
    Matrix();
    Matrix(int);
    Matrix(int,int);
    Matrix(int,int,int);
    void CreateMatrix(int,int);
    void FillingMatrix();
    Matrix operator+ (Matrix &Ob1);
    Matrix& operator= (Matrix &Ob1);
    void ViewMatrix();
    void ClearMatrix();
    ~Matrix();
    };

    Matrix::Matrix()
    {
    n=m=1;
    CreateMatrix(n,m);
    FillingMatrix();
    };

    Matrix::Matrix(int _n, int _m)
    {
    n=_n;
    m=_m;
    CreateMatrix(n,m);
    FillingMatrix();
    };

    Matrix::Matrix(int _n, int _m, int o)
    {
    n = _n;
    m = _m;
    CreateMatrix(n,m);
    };

    Matrix::Matrix(int x)
    {
    m=n=1;
    CreateMatrix(1,1);
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    if (i==j)
    {
    M[i][j]=x;
    }
    else M[i][j] = 0;
    };
    };

    void Matrix::CreateMatrix(int _n, int _m)
    {
    M = new int* [_n];
    for (int i=0; i<_n; i++)
    {
    M[i] = new int [_m];
    };
    }

    void Matrix::FillingMatrix()
    {

    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    M[i][j] = rand()%50;
    };
    };

    Matrix Matrix::operator+ (Matrix &Ob1)
    {
    Matrix temp(Ob1.n,Ob1.m,0);
    if (n!=Ob1.n || m!=Ob1.m)
    {
    printf("Inpossible\n");
    system("pause");
    return 1;
    };
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    temp.M[i][j] = M[i][j] + Ob1.M[i][j];
    };
    return temp;
    };

    Matrix &Matrix::operator= (Matrix &Ob1)
    {
    ClearMatrix();
    n = Ob1.n;
    m = Ob1.m;
    CreateMatrix(n,m);
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    M[i][j]=Ob1.M[i][j];
    };
    return *this;
    };

    void Matrix::ViewMatrix()
    {
    for (int i=0; i<n; i++)
    {
    for (int j=0; j<m; j++)
    {
    printf("%4d",M[i][j]);
    };
    cout<<'\n';
    };
    cout<<'\n';
    };

    void Matrix::ClearMatrix()
    {
    for (int i=0; i<n; i++)
    {
    delete[] M[i];
    };
    delete[] M;
    m=n=1;
    };

    Matrix::~Matrix()
    {
    for (int i=0; i<n; i++)
    delete [] M[i];
    delete[] M;
    };

    int main()
    {
    Matrix x(3,2), y(3,2),z;
    srand(time(NULL));
    x.ViewMatrix();
    y.ViewMatrix();
    z = x+y;
    z.ViewMatrix();
    system("pause");
    return 0;
    }
    Если деструктор убрать, то программа нормально работает, но если он присутствует, то на этапе "z = x + y" выдает ошибку. Почему?
     
  2. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Давай по порядку. Какую ошибку выдает?
     
  3. kleiner

    kleiner Гость

    Исправленный код:
    <!--shcode--><pre><code class='#CPP'>#include<iostream>
    #include<cstdio>
    #include<time.h>
    #include<cstdlib>

    using namespace std;

    class Matrix
    {
    int n; //strioki
    int m; //stolbiki
    int **M; //sobstvenno matrix
    public:
    Matrix();
    Matrix(const Matrix& aMatrix);
    Matrix(int);
    Matrix(int,int);
    Matrix(int,int,int);
    void CreateMatrix(int,int);
    void FillingMatrix();
    Matrix& operator+ (Matrix &Ob1);
    Matrix& operator= (Matrix &Ob1);
    void ViewMatrix();
    void ClearMatrix();
    ~Matrix();
    };

    Matrix::Matrix()
    {
    n=m=1;
    CreateMatrix(n,m);
    FillingMatrix();
    };

    Matrix::Matrix(int _n, int _m)
    {
    n=_n;
    m=_m;
    CreateMatrix(n,m);
    FillingMatrix();
    };

    Matrix::Matrix(int _n, int _m, int o)
    {
    n = _n;
    m = _m;
    CreateMatrix(n,m);
    };

    Matrix::Matrix(int x)
    {
    m=n=1;
    CreateMatrix(1,1);
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    if (i==j)
    {
    M[j]=x;
    }
    else M[j] = 0;
    };
    };


    Matrix::Matrix(const Matrix& aMatrix)
    {
    n = aMatrix.n;
    m = aMatrix.m;
    CreateMatrix(n,m);
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    M[j]=aMatrix.M[j];
    };
    }

    void Matrix::CreateMatrix(int _n, int _m)
    {
    M = new int* [_n];
    for (int i=0; i<_n; i++)
    {
    M = new int [_m];
    };
    }

    void Matrix::FillingMatrix()
    {

    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    M[j] = rand()%50;
    };
    };

    Matrix& Matrix::eek:perator+ (Matrix &Ob1)
    {
    static Matrix temp(Ob1.n,Ob1.m,0);
    if (n!=Ob1.n || m!=Ob1.m)
    {
    printf("Inpossible\n");
    system("pause");
    return temp;
    };
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    temp.M[j] = M[j] + Ob1.M[j];
    };
    return temp;
    };

    Matrix &Matrix::eek:perator= (Matrix &Ob1)
    {
    ClearMatrix();
    n = Ob1.n;
    m = Ob1.m;
    CreateMatrix(n,m);
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++)
    {
    M[j]=Ob1.M[j];
    };
    return *this;
    };

    void Matrix::ViewMatrix()
    {
    for (int i=0; i<n; i++)
    {
    for (int j=0; j<m; j++)
    {
    printf("%4d",M[j]);
    };
    cout<<'\n';
    };
    cout<<'\n';
    };

    void Matrix::ClearMatrix()
    {
    for (int i=0; i<n; i++)
    {
    delete[] M;
    };
    delete[] M;
    m=n=1;
    };

    Matrix::~Matrix()
    {
    for (int i=0; i<n; i++)
    delete [] M;
    delete[] M;
    };

    int main()
    {
    Matrix x(3,2), y(3,2),z;
    srand(time(NULL));
    x.ViewMatrix();
    y.ViewMatrix();
    z = x+y;
    z.ViewMatrix();
    system("pause");
    return 0;
    }[/CODE]
    Добавлен конструктор копирования. Изменён тип возвращаемого значения оператора сложения. Объект temp в операторе сложения сделан статическим.
    В принципе, без конструктора копирования можно было бы обойтись, но на всякий случай пусть будет.
    Вероятная причина ошибки заключается по-видимому в том, что оператор сложения раньше возвращал не ссылку, а копию объекта, при этом создавался временный объект, но поскольку отсутствовал конструктор копирования, присходило простое побитовое присваивание объекта temp временному объекту, в результате чего просто тупо копировался указатель на матрицу, затем вызывался деструктор, который убивал объект temp и в результате указатель М указывал непонятно на что. Это видимо и приводило к краху программы.
    Кстати компилятор G++ вообще отказывался собирать код, пока возвращаемый оператором сложения тип не был изменён на ссылку.
     
Загрузка...

Поделиться этой страницей