Класс с матрицами
Заранее благодарен
#include <conio.h>
#include <math.h>
const int l=2;
const int s=2;
int f;
class matrix { // класс матрица
private:
int **matr;
void Create()
{
matr = new int*[l];
for (int z=0; z<s; z++)
matr[z] = new int;
}
public:
matrix (int l,int s){Create();};
int* operator[](int i) { return matr; }
const int* operator[](int i) const { return matr; }
matrix operator+(const matrix & b);
matrix operator-(const matrix & b);
matrix operator*(const matrix & b);
matrix operator*(int f);
void In_put();
void Out_put();
int GetElement(int i,int j);
~matrix()
{
for (int z=0; z<l; z++)
delete[] matr[z];
delete[] matr;
}
};
int matrix::GetElement(int i,int j)
{
matrix q(l,s);
return q.matr[j];}
matrix matrix::operator*(const matrix & b)
{
int i,j,k;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
for (k=0; k<l; k++)
c[j]+=b[k]*(*this)[k][j];
return c;
};
matrix matrix::operator * (int f)
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=((*this)[j])*f;
return c;
};
matrix matrix::operator + (const matrix & b)
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=b[j]+(*this)[j];
return c;
};
matrix matrix::operator-(const matrix & b)
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=b[j]-(*this)[j];
return c;
};
void matrix::Out_put()
{
matrix d(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++) { cout<<""<<(d[j]);}
cout<<endl;}
};
void matrix::In_put()
{
matrix e(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++)
{cin>>(e[j]);}}
};
int main()
{
int f;
matrix m1(l,s), m2(l,s), m(l,s);
cout << "\nMatrix 1: \n";
m1.In_put();
cout << "\nMatrix 2: \n";
m2.In_put();
m=m1+m2;
cout << "\n Matrix 1 + Matrix 2 : \n";
m.Out_put();
cout << "\n";
m=m1-m2;
cout << "\n Matrix 1 - Matrix 2 : \n";
m.Out_put();
cout << "\n";
m=m1*m2;
cout << "\n Matrix 1 * Matrix 2 :\n";
m.Out_put();
cout << "\n";
cout<<"Enter f:";cin>>f;
m=m1*f;
cout << "\n Matrix 1 * f :\n";
m.Out_put();
m=m2*f;
cout << "\n Matrix 2 * f :\n";
m.Out_put();
return 0;
};
Родной ты наш, ошибку-то какую выдаёт? Что выдаёт? У меня хрустальный шар сломался.
Несуразностей столько, что не знаю, на что в первую очередь обращать внимание.
Для чего глобальные переменные? Все данные класса должны храниться внутри этого класса.
Имена l, s, f ни о чём не говорит. По названию этих переменных невозможно понять, для чего они предназначены.
Про области видимости и локальные переменные топикстартер явно не знает.
Остановлюсь на этом:
{
matrix e(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++)
{cin>>(e[j]);}}
};
Здесь создаётся локальный экземпляр класса, в него заносятся данные, а после выхода из этого метода, экземпляр прекращает существование - данные теряются.
PS И, да, не мешало бы использовать более новую среду разработки и компилятор.
да нормально собирается:)
#include <conio.h>
#include <math.h>
using namespace std;
const int l=2;
const int s=2;
int f;
class matrix { // класс матрица
private:
int **matr;
void Create()
{
matr = new int*[l];
for (int z=0; z<s; z++)
matr[z] = new int;
}
public:
matrix (int l,int s){Create();};
int* operator[](int i) { return matr; }
const int* operator[](int i) const { return matr; }
matrix operator+(const matrix & b);
matrix operator-(const matrix & b);
matrix operator*(const matrix & b);
matrix operator*(int f);
void In_put();
void Out_put();
int GetElement(int i,int j);
~matrix()
{
for (int z=0; z<l; z++)
delete[] matr[z];
delete[] matr;
}
};
int matrix::GetElement(int i,int j)
{
matrix q(l,s);
return q.matr[j];}
matrix matrix::operator*(const matrix & b)
{
int i,j,k;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
for (k=0; k<l; k++)
c[j]+=b[k]*(*this)[k][j];
return c;
};
matrix matrix::operator * (int f)
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=((*this)[j])*f;
return c;
};
matrix matrix::operator + (const matrix & b)
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=b[j]+(*this)[j];
return c;
};
matrix matrix::operator-(const matrix & b)
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=b[j]-(*this)[j];
return c;
};
void matrix::Out_put()
{
matrix d(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++) { cout<<""<<(d[j]);}
cout<<endl;}
};
void matrix::In_put()
{
matrix e(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++)
{cin>>(e[j]);}}
};
int main()
{
int f;
matrix m1(l,s), m2(l,s), m(l,s);
cout << "\nMatrix 1: \n";
m1.In_put();
cout << "\nMatrix 2: \n";
m2.In_put();
m=m1+m2;
cout << "\n Matrix 1 + Matrix 2 : \n";
m.Out_put();
cout << "\n";
m=m1-m2;
cout << "\n Matrix 1 - Matrix 2 : \n";
m.Out_put();
cout << "\n";
m=m1*m2;
cout << "\n Matrix 1 * Matrix 2 :\n";
m.Out_put();
cout << "\n";
cout<<"Enter f:";cin>>f;
m=m1*f;
cout << "\n Matrix 1 * f :\n";
m.Out_put();
m=m2*f;
cout << "\n Matrix 2 * f :\n";
m.Out_put();
return 0;
};
Зачем там вообще внешние данные? Класс в си++, по сути, та же структура в чистом си,
только с расширенными возможностями, и методы не являются функциями членами.
А отличия ключевых слов "class" и "struct" в си++ заключаются в том, что при "struct"
все члены по дефолту являются публичными, и при "class" -- приватными.
А потому писать вначале описания класса модификатор "private:" излишне,
ибо с самого начала и так всё приватное.
И вообще, можно было сделать примерно так:
{
int matrixData[2][2];
// тут объявляем методы.
};
Всё. Больше для данной задачи ничего не нужно.
Конструктор опционально нужен, для инициализации данных (в 0 например).
Деструктор тут не нужен вообще.
Давно не юзал C++, что нашёл с ходу:
{
matrix d(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++) { cout<<""<<(d[j]);}
cout<<endl;}
};
void matrix::In_put()
{
matrix e(l,s);
for(int i=0;i<l;i++)
{
for(int j=0;j<s;j++)
{cin>>(e[j]);}}
};
matrix e(l,s) и matrix d(l,s) - не правильно, нужно как-то так(мы же вводим матрицу объекта и выводим её же):
for(int i=0;i<l;i++) {
for(int j=0;j<s;j++) { cout<<""<<(this->matr[j]); }
cout<<endl;
}
};
void matrix::In_put() {
for(int i=0;i<l;i++) {
for(int j=0;j<s;j++) {
cin>>(this->matr[j]);
}
}
};
Сама ошибка вываливается на строчке:
После второго вызова деструктора, почему - не знаю, нету желания сидеть в дебаге кучу времени(в случаях когда ошибка возникает в непонятном месте не твоего кода - спасает Call Stack из Visual Studio). Судя по всему у тебя где-то там ошибка с инициализацией памяти.
2kissko:
Код вполне нормален для ООП. Хотя методы In_put() и Out_put() можно было и вынести из класса. Деструктор нужен для очистки памяти. А вот внешние константы стоило бы сменить на параметра конструктора и задавать ими, динамически, размерность матрицы внутри класса.
Писать private - дело вкуса и стиля.
п.с. топикстартер - почитай что-нибудь про стиль оформление кода(пробельные символы, отступы и расстановку фигурных скобок), тебе это пригодится.
п.с.с. кодер уже написал про локальные области видимости.
{
matr = new int*[l];
for (int z=0; z<s; z++)
matr[z] = new int;
}
Когда используются многомерные массивы, особенно динамические, они просто инициализируются как одномерные,
без таких вот выкрутасов. Индекс вычисляется из многомерного в одномерный перемножением.
А когда нужно просто обработать все элементы, без привязки к какому то измерению, так же можно (и нужно)
работать как с одномерным массивом, без нескольких вложённых циклов. Память при этом выделяется один раз, сразу для всего массива.
И ещё становится возможным создавать массивы с динамической размеренностью, задаваемой при инициализации.
{
int i,j;
matrix c(l,s);
for (i=0;i<l;i++)
for (j=0;j<s;j++)
c[j]=b[j]+(*this)[j];
return c;
};
В перегруженных операторах создаётся новый экземпляр класса в локальной переменной.
Туда помещается результат выполнения. При этом, в переменной хранится указатель на массив.
Когда же этот код завершает работу, переменная удаляется. А ещё срабатывает деструктор,
и освобождает память. В результате, здесь возвращается указатель на не выделенную (освобождённую) память.
Решения тут два -- либо хранить данные в структуре класса, либо не создавать новый экземпляр, а вносить изменения в текущий,
и возвращать на него ссылку.
Деструктор нужен, если в структуре класса используется указатель, а данные хранятся в отдельной, выделенной памяти (как сейчас).
Исли же массив статичен -- то данные можно хранить в структуре класса, и деструктор ни к чему, поскольку память не выделялась.
#include <iostream>
#include <conio.h>
#include <math.h>
using namespace std;
#define MATRIX_SIZE_X 2
#define MATRIX_SIZE_Y 2
class matrix { // класс матрица
private:
int *mData;
int mSizeY;
int mSizeX;
int refCount;
public:
matrix (int sx,int sy)
{
int i=0;
mSizeY = sy;
mSizeX = sx;
refCount = 0;
mData = new int[sy*sx];
while(i<(sy*sx)){mData[i++]=0;};
};
~matrix() {if((refCount--)<1){delete[] mData;}}
int operator[](int i){return mData;}
matrix operator=(matrix &b);
matrix operator+(matrix &b);
matrix operator-(matrix &b);
matrix operator*(matrix &b);
matrix operator*(int f);
void In_put();
void Out_put();
};
matrix matrix::operator = (matrix &b)
{
int i=0; refCount++;
while(i<(mSizeY*mSizeX)){mData=b;i++;}
return *this;
};
matrix matrix::operator * (matrix &b)
{
int i=0; refCount++;
while(i<(mSizeY*mSizeX)){mData[i++]*=b;i++;}
return *this;
};
matrix matrix::operator * (int f)
{
int i=0; refCount++;
while(i<(mSizeY*mSizeX)){mData[i++]*=f;}
return *this;
};
matrix matrix::operator + (matrix &b)
{
int i=0; refCount++;
while(i<(mSizeY*mSizeX)){mData+=b;i++;}
return *this;
};
matrix matrix::operator - (matrix &b)
{
int i=0; refCount++;
while(i<(mSizeY*mSizeX)){mData-=b;i++;}
return *this;
};
void matrix::Out_put()
{
for(int i=0;i<mSizeY;i++)
{
for(int j=0;j<mSizeX;j++)
{printf("[%d,%d]=%u ",j,i,mData[(i*mSizeX)+j]);}
cout<<endl;
}
cout<<endl;
};
void matrix::In_put()
{
for(int i=0;i<mSizeY;i++)
{
for(int j=0;j<mSizeX;j++){cin>>(mData[(i*mSizeX)+j]);}
}
};
int _tmain(int argc, _TCHAR **argv)
{
matrix m(MATRIX_SIZE_X, MATRIX_SIZE_Y);
matrix m1(MATRIX_SIZE_X, MATRIX_SIZE_Y);
matrix m2(MATRIX_SIZE_X, MATRIX_SIZE_Y);
int f=0;
cout << "\nMatrix 1: \n";
m1.In_put();
cout << "\nMatrix 2: \n";
m2.In_put();
m=m1+m2;
cout << "\n Matrix 1 + Matrix 2 : \n";
m.Out_put();
cout << "\n";
m=m1-m2;
cout << "\n Matrix 1 - Matrix 2 : \n";
m.Out_put();
cout << "\n";
m=m1*m2;
cout << "\n Matrix 1 * Matrix 2 :\n";
m.Out_put();
cout << "\n";
cout<<"Enter f:";cin>>f;
m=m1*f;
cout << "\n Matrix 1 * f :\n";
m.Out_put();
m=m2*f;
cout << "\n Matrix 2 * f :\n";
m.Out_put();
return 0;
}
Только методы изменяют текущий класс. А по другому простыми способами никак. В C++ нет сборщика мусора, это не Java.