Страница 1 из 1

Перегрузка операций

Добавлено: 26 май 2010, 10:44
Iworb
Написал программу, но выдает ошибку в 184 строке, вот теперь думаю как правильно перегрузить операторы + и ~ чтобы они нормально друг с другом работали
Само задание:
(А[(B[3.7])] +( C +(~A)))
M[К] – возвращается сумма элементов столбцов М, имеющих минимальное значение < К.
~М – элементы столбцов переставить в обратном порядке, если первый элемент >0, в противном случае отсортировать по убыванию.
М3=М1+М2 // M3[i,j] = M2[i,j] + M1[i,j], для элементов, расположенных по периметру матриц. Остальные элементы равны соответствующим элементам М2.

Вычисляеть его надо соответственно показывая каждое действие после вычисленя.

Код: Выделить всё

#include <iostream>
#include <iomanip>
#include <conio.h>
#include <windows.h>
#include <time.h>
using namespace std;

class Matrix
{
	protected:
		float *matr;
		int n,m;
	public:
		Matrix(int n, int m);
		~Matrix() {delete[] matr; cout<<"matrix kill"<<endl;}
		Matrix(Matrix &a);
		Matrix& operator=(Matrix& a);
		Matrix& operator~();
		Matrix operator+(Matrix &a);
		float operator[](float K);
		int _n() {return n;}
		int _m() {return m;}
		float _matr(int i, int j) {if((i>=0&&i<n)&&(j>=0&&j<m)) return *(matr+i*n+j);}
		void matr_(int i, int j, float el) {if((i>=0&&i<n)&&(j>=0&&j<m)) *(matr+i*n+j)=el;}
		friend void form(Matrix &a);
		friend void print(Matrix &a);
		friend Matrix operator+(float l, Matrix &a);
};

	Matrix::Matrix(int n, int m)
	{
		int i,a;
		cout<<"matrix done"<<endl;
		this->n=n;
		this->m=m;
		matr=new float[n*m];
		for(i=0;i<n;i++)
		for(a=0;a<m;a++)
		matr_(i,a,(-50+100.*rand()/(RAND_MAX+1)));
	}
	
	Matrix::Matrix(Matrix &a)
	{
		n=a.n;
		m=a.m;
		matr=new float[n*m];
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		matr_(i,j,a._matr(i,j));
		cout<<"matrix copy"<<endl;
	}
	
	Matrix& Matrix: :o perator=(Matrix& a)
	{
		if(this!=&a)
		{
			n=a.n;
			m=a.m;
			if(matr!=NULL) delete[] matr;
			matr=new float[n*m];
   			for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			matr_(i,j,a._matr(i,j));
		}
		return *this;
	}
	
	float Matrix: :o perator[](float K)
	{
		float ret=0;
		for(int i=0;i<n;i++)
		{
			float min_t=32000;
			for(int j=0;j<m;j++)
			{
				if(_matr(j,i)<min_t) min_t=_matr(j,i);
			}
			if(min_t<K) for(int j=0;j<m;j++) ret+=_matr(j,i);
		}
		return ret;
	}

	Matrix& Matrix: :o perator~()
	{
		float tmp;
		int i,a,k;
		if(_matr(0,0)>0)
		{
			for(a=0;a<m;a++)
			{
				for(i=0;i<(int)(n/2);i++)
				{
					tmp=_matr(i,a);
					matr_(i,a,_matr(n-i-1,a));
					matr_(n-i-1,a,tmp);
				}
			}
		}
		else
		{
			for(a=0;a<m;a++)
			{
				for(i=0;i<n-1;i++)
				{
					for(k=i+1;k<n;k++)
					{
						if(_matr(i,a)<_matr(k,a))
						{
							tmp=_matr(i,a);
							matr_(i,a,_matr(k,a));
							matr_(k,a,tmp);
						}
					}
				}
			}
		}
		return *this;
	}

	Matrix Matrix: :o perator+(Matrix &a)
	{
		int i,j;
		int n1=n<a._n()?n:a._n();
		int m1=m<a._m()?m:a._m();
		Matrix res(n1,m1);
		for(i=0;i<n1;i++)
		for(j=0;j<m1;j++)
		res.matr_(i,j,a._matr(i,j));
		for(i=0;i<m1;i++) res.matr_(0,i,res._matr(0,i)+_matr(0,i));
		for(i=1;i<n1;i++) res.matr_(i,m1-1,res._matr(i,m1-1)+_matr(i,m1-1));
		for(i=m1-2;i>=0;i--) res.matr_(n1-1,i,res._matr(n1-1,i)+_matr(n1-1,i));
		for(i=n1-2;i>0;i--) res.matr_(i,0,res._matr(i,0)+_matr(i,0));
		return res;
	}

void form(Matrix &a)
{
	for(int i=0;i<a._n();i++)
	for(int j=0;j<a._m();j++)
	a.matr_(i,j,100.*rand()/(RAND_MAX+1));
}

void print(Matrix &a)
{
	for(int i=0;i<a.n;i++)
	{
		for(int j=0;j<a.m;j++)
		cout<<setw(9)<<setprecision(4)<<a._matr(i,j);
		cout<<endl;
	}
}

Matrix operator+(float l, Matrix &a)
{
	Matrix res(a);
	for(int i=0;i<a._n();i++)
	for(int j=0;j<a._m();j++)
	res.matr_(i,j,res._matr(i,j)+l);
	return res;
}

int main()
{
	srand((unsigned) time(NULL));
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	Matrix A(5,5);
	Matrix B(6,6);
	Matrix C(7,7);
	cout<<"Matrix A:"<<endl;
	print(A);
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"Matrix B:"<<endl;
	print(B);
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"Matrix C:"<<endl;
	print(C);
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"B[3.7]="<<B[3.7]<<endl<<"A[(B[3.7])]="<<A[(B[3.7])]<<endl;
	cout<<"Matrix ~A:"<<endl;
	print(~A);
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"Matrix C+(~A):"<<endl;
	print(C+(~A));//тут выдает ошибку
	cout<<"----------------------------------------------------------------------"<<endl;
    getch();
    return 0;
}

Re: Перегрузка операций

Добавлено: 26 май 2010, 11:15
Iworb
можно еще сделать так:

Код: Выделить всё

Matrix& Matrix: :o perator+(Matrix &a)
	{
		int i,j;
		for(i=0;i<a._m();i++) a.matr_(0,i,a._matr(0,i)+_matr(0,i));
		for(i=1;i<a._n();i++) a.matr_(i,a._m()-1,a._matr(i,a._m()-1)+_matr(i,a._m()-1));
		for(i=a._m()-2;i>=0;i--) a.matr_(a._n()-1,i,a._matr(a._n()-1,i)+_matr(a._n()-1,i));
		for(i=a._n()-2;i>0;i--) a.matr_(i,0,a._matr(i,0)+_matr(i,0));
		return a;
	}
но работает неправильно... :confused:

Re: Перегрузка операций

Добавлено: 27 май 2010, 07:09
Vasilisk
Iworb писал(а):Написал программу, но выдает ошибку в 184 строке, вот теперь думаю как правильно перегрузить операторы + и ~ чтобы они нормально друг с другом работали
}

Ты силён в устном счёте! У меня так не получается в тексте отсчитать 184 строку, чтобы увидеть саму конструкцию, вызывающую проблемы - я сбиваюсь раньше... :(

Re: Перегрузка операций

Добавлено: 27 май 2010, 09:48
Iworb
у меня просто строки подписывает))) 4 строка снизу))
Но я уже переделал программку - правда работает неправильно как-то - может гляните?

Код: Выделить всё

/*(À[(B[3.7])] +( C +(~A)))
M[Ê] - âîçâðàùàåòñÿ ñóììà ýëåìåíòîâ ñòîëáöîâ Ì, èìåþùèõ ìèíèìàëüíîå çíà÷åíèå < Ê.
~Ì - ýëåìåíòû ñòîëáöîâ ïåðåñòàâèòü â îáðàòíîì ïîðÿäêå, åñëè ïåðâûé ýëåìåíò >0, â ïðîòèâíîì ñëó÷àå îòñîðòèðîâàòü ïî óáûâàíèþ. 
Ì3=Ì1+Ì2 // M3[i,j] = M2[i,j] + M1[i,j], äëÿ ýëåìåíòîâ, ðàñïîëîæåííûõ ïî ïåðèìåòðó ìàòðèö. Îñòàëüíûå ýëåìåíòû ðàâíû ñîîòâåòñòâóþùèì ýëåìåíòàì Ì2.*/
#include <iostream>
#include <iomanip>
#include <conio.h>
#include <windows.h>
#include <time.h>
using namespace std;

class Matrix
{
	protected:
		float *matr;
		int n,m;
		friend ostream& operator<<(ostream& o, Matrix& a);
	public:
		Matrix(int n, int m);
		~Matrix() {delete[] matr; cout<<"matrix kill"<<endl;}
		Matrix(Matrix &a);
		Matrix& operator=(Matrix& a);
		Matrix& operator~();
		Matrix& operator+(Matrix &a);
		float operator[](float K);
		int _n() {return n;}
		int _m() {return m;}
		float _matr(int i, int j) {if((i>=0&&i<n)&&(j>=0&&j<m)) return *(matr+i*n+j);}
		void matr_(int i, int j, float el) {if((i>=0&&i<n)&&(j>=0&&j<m)) *(matr+i*n+j)=el;}
		friend void form(Matrix &a);
		friend void print(Matrix &a);
		friend Matrix operator+(float l, Matrix &a);
};

	Matrix::Matrix(int n, int m)
	{
		int i,a;
		cout<<"matrix done"<<endl;
		this->n=n;
		this->m=m;
		matr=new float[n*m];
		for(i=0;i<n;i++)
		for(a=0;a<m;a++)
		matr_(i,a,(-50+100.*rand()/(RAND_MAX+1)));
	}
	
	Matrix::Matrix(Matrix &a)
	{
		n=a.n;
		m=a.m;
		matr=new float[n*m];
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		matr_(i,j,a._matr(i,j));
		cout<<"matrix copy"<<endl;
	}
	
	Matrix& Matrix: :o perator=(Matrix& a)
	{
		if(this!=&a)
		{
			n=a.n;
			m=a.m;
			if(matr!=NULL) delete[] matr;
			matr=new float[n*m];
   			for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
			matr_(i,j,a._matr(i,j));
		}
		return *this;
	}
	
	float Matrix: :o perator[](float K)
	{
		float ret=0;
		for(int i=0;i<n;i++)
		{
			float min_t=32000;
			for(int j=0;j<m;j++)
			{
				if(_matr(j,i)<min_t) min_t=_matr(j,i);
			}
			if(min_t<K) for(int j=0;j<m;j++) ret+=_matr(j,i);
		}
		return ret;
	}

	Matrix& Matrix: :o perator~()
	{
		float tmp;
		int i,a,k;
		if(_matr(0,0)>0)
		{
			for(a=0;a<m;a++)
			{
				for(i=0;i<(int)(n/2);i++)
				{
					tmp=_matr(i,a);
					matr_(i,a,_matr(n-i-1,a));
					matr_(n-i-1,a,tmp);
				}
			}
		}
		else
		{
			for(a=0;a<m;a++)
			{
				for(i=0;i<n-1;i++)
				{
					for(k=i+1;k<n;k++)
					{
						if(_matr(i,a)<_matr(k,a))
						{
							tmp=_matr(i,a);
							matr_(i,a,_matr(k,a));
							matr_(k,a,tmp);
						}
					}
				}
			}
		}
		return *this;
	}

	Matrix& Matrix: :o perator+(Matrix &a)
	{
		int i,j;
		int m_m=_m()<a._m()?_m():a._m();
		int m_n=_n()<a._n()?_n():a._n();
		for(i=0;i<m_m;i++) a.matr_(0,i,a._matr(0,i)+_matr(0,i));
		for(i=1;i<m_n;i++) a.matr_(i,m_m-1,a._matr(i,m_m-1)+_matr(i,m_m-1));
		for(i=m_m-2;i>=0;i--) a.matr_(m_n-1,i,a._matr(m_n-1,i)+_matr(m_n-1,i));
		for(i=m_n-2;i>0;i--) a.matr_(i,0,a._matr(i,0)+_matr(i,0));
		return a;
	}

void form(Matrix &a)
{
	for(int i=0;i<a._n();i++)
	for(int j=0;j<a._m();j++)
	a.matr_(i,j,100.*rand()/(RAND_MAX+1));
}

void print(Matrix &a)
{
	for(int i=0;i<a.n;i++)
	{
		for(int j=0;j<a.m;j++)
		cout<<setw(9)<<setprecision(4)<<a._matr(i,j);
		cout<<endl;
	}
}

Matrix operator+(float l, Matrix &a)
{
	Matrix res(a);
	for(int i=0;i<a._n();i++)
	for(int j=0;j<a._m();j++)
	res.matr_(i,j,res._matr(i,j)+l);
	return res;
}

ostream& operator<<(ostream& o, Matrix& a)
{
	for(int i=0;i<a.n;i++)
	{
		for(int j=0;j<a.m;j++)
		o<<setw(9)<<setprecision(4)<<a._matr(i,j);
		o<<endl;
	}
	return o;
}

int main()
{
	srand((unsigned) time(NULL));
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	Matrix A(5,5);
	Matrix B(6,6);
	Matrix C(7,7);
	cout<<"Matrix A:"<<endl;
	cout<<A;
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"Matrix B:"<<endl;
	cout<<B;
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"Matrix C:"<<endl;
	cout<<C;
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"B[3.7]="<<B[3.7]<<endl<<"A[(B[3.7])]="<<A[(B[3.7])]<<endl;
	cout<<"Matrix ~A:"<<endl;
	cout<<(~A);
	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"Matrix C+(~A):"<<endl;
	cout<<(C+(~A));
	cout<<"----------------------------------------------------------------------"<<endl;
    getch();
    return 0;
}

Re: Перегрузка операций

Добавлено: 27 май 2010, 19:53
Vasilisk
Iworb писал(а):у меня просто строки подписывает))) 4 строка снизу))
Я же говорю - ты силён. А может быть - ты даже и из инопланетной цивилизации? "У меня" так не подписывает никакие строки, и я для того, чтобы выяснить строку по номеру вынужден пользоваться специальными программами. Т.е. мне надо её загрузить, скопировать туда твой текст... И это - только для того, чтобы мне понять, могу ли я тебе чем-нибудь помочь. А оно мне надо, как ты думаешь? Вопрос надо задавать настолько коротко, насколько это возможно. В твоём случае достаточно описания класса и строки, в которой оно не работает, как тобой ожидается. С описанием "хочу так", "сделал вот как", "получаю вот что"... "ПОЧЕМУ?" Вот пример того, как такие вопросы задаются http://phpforum.ru/index.php?act=ST&f=12&t=29193

Никто здесь не будет разбираться в логике твоей программы (если сам вопрос не о логике) и тем более, городить себе проект, чтобы её скомпилировать. Если хочешь, чтобы компилировали - прикладывай такой проект в аттаче... но это - уже совершенно в злокачественном случае, например - ошибка компилятора в том месте, в котором всё по правилам.

В данном же случае я вижу вот что:

class Matrix{
public:
Matrix operator+(Matrix &a);
Matrix& operator~();

* * *
};
cout<<"Matrix C+(~A):"<<endl;
cout<<(C+(~A));

Насколько я помню, при перегрузке оператора происходит следующее - this используется только как источник типа (т.е. информация компилятору метод какого класса вызвать), а сам операнд попадает в метод тем путём, каким и все прочие операнды. Т.е. перегруженный ~ это operator ~(const Matrix &a). Но конструкция operator~() - синтаксически выглядит, как попытка перегрузки деструктора :) Соответственно, непонятно, что такое ~A - если это явный вызов деструктора (я не разбирался в логике твоей программы и не знаю, что ты хочешь сделать этим действием), то ему не хватает скобок, т.е. ~A(); А если это вызов перегруженной операции ~, то в объявлении перегруженного оператора ему не передаётся никакого операнда... И я не понимаю, почему в данном случае компилятор молчит - он должен был тебе сказать примерно то же самое, что сказал сейчас я.