Сумма Матриц

  • Автор темы BadWolf
  • Дата начала
B

BadWolf

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

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" выдает ошибку. Почему?
 
K

kleiner

#3
Исправленный код:
<!--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++ вообще отказывался собирать код, пока возвращаемый оператором сложения тип не был изменён на ссылку.