4. TÓPICOS AVANÇADOS
4.1.2. OPERADORES E FRIENDS
Vamos tomar o exemplo do tipo abstrato de dados fração de 1.4.1 e acrescentar sobrecarga de operador e funções friends. Fica faltando somente tratamento de exceções que é sugerido como exercício no capítulo respectivo.
Tópicos abordados:
Sobrecarga de operador, "copy constructor" ,funções friends. É uma implementação bastante completa e portável de um TAD, use como referência para sintaxe de sobrecarga de operadores.
---
long mdc(long n,long d) //metodo de Euclides { if (n<0) n=-n; if (d<0) d=-d; while (d!=0) { long r=n % d; // %=MOD n=d; } return n; private: long num;
//maximo divisor comum
d=r; }; class fracao { long den; public: void simplifica(void); //simplificacao fracao(fracao &t); //copy constructor fracao() {num=0; den=1;}
//construtor vazio.
fracao(const long t,const long m); fracao(const long t) {num=t;den=1;}
friend int operator!= (const fracao& s,const fracao& t);
fracao& operator*= (const fracao& t); ~fracao() {};
//Nao precisa fazer nada
long get_num(void) {return num;} long get_den(void) {return den;}
//operacoes matematicas basicas
friend fracao operator+ (const fracao& f,const fracao& j); friend fracao operator- (const fracao& f,const fracao& j); friend fracao operator* (const fracao& f,const fracao& j); friend fracao operator/ (const fracao& f,const fracao& j);
//operadores de comparacao
friend int operator== (const fracao& s,const fracao& t);
friend int operator>= (const fracao& s,const fracao& t); friend int operator<= (const fracao& s,const fracao& t); friend int operator> (const fracao& s,const fracao& t); friend int operator< (const fracao& s,const fracao& t);
//operadores de atribuicao
fracao& operator= (const fracao& t); fracao& operator+= (const fracao& t); fracao& operator-= (const fracao& t);
friend istream& operator>> (istream& ci,fracao& f); friend ostream& operator<< (ostream& co,const fracao& f);
operator float() const;
---
#include <math.h>
//operadores de input output
//operadores de conversao de tipos operator double() const;
operator long() const; operator int() const; };
#endif
//codigo para a classe fracao #include <iostream.h> #include <iomanip.h> #include <stdio.h> #include "of.h" fracao::fracao(fracao &t) //copy constructor { num=t.num;
den=t.den; } { simplifica(); void fracao::simplifica(void) { long commd;
commd=mdc(num,den); //divisor comum num=num/commd;
den=den/commd;
if (den<0) { den=-den; num=-num;}; //move o sinal p/ cima
}
fracao& fracao::operator+= (const fracao& t)
num=num*t.den+den*t.num; den=den*t.den;
return *this; }
fracao::fracao(const long t,const long m) { num=t; den=m; simplifica(); //this->simplifica }
fracao g(f.num*j.den,f.den*j.num);
//como private.
}
fracao g((f.num*j.den)-(f.den*j.num),j.den*f.den); fracao operator/ (const fracao& f,const fracao& j) {
g.simplifica();
//esse metodo nao pertence a g, mas ela chama
//g.simplifica(); isto e' permitido aqui mesmo com simplifica
return g; }
fracao operator+ (const fracao& f,const fracao& j) {
fracao g((f.num*j.den)+(f.den*j.num),j.den*f.den); //retorna variavel
g.simplifica(); return g;
fracao operator- (const fracao& f,const fracao& j) {
//retorna variavel g.simplifica(); return g;
}
{
fracao operator* (const fracao& f,const fracao& j) { fracao g(f.num*j.num,f.den*j.den); //(f.num*j.num)/(f.den*j.den) g.simplifica(); return g; }
ostream& operator<< (ostream& co,const fracao& f)
co << "(" << f.num << "/" << f.den << ")"; return co;
}
istream& operator>> (istream& ci, fracao& f) {
long gcdiv;
//melhorar, ler mais sobre cin. ci >> f.num >> f.den; gcdiv=mdc(f.num,f.den); f.num=f.num/gcdiv; f.den=f.den/gcdiv; return ci; }
{
return ((s.num*t.den)==(s.den*t.num)); //veja operacoes matematicas com fracao }
int operator!= (const fracao& s,const fracao& t) {
return ((s.num*t.den)!=(s.den*t.num)); }
int operator<= (const fracao& s,const fracao& t) {
return ((s.num*t.den)<=(s.den*t.num)); }
int operator< (const fracao& s,const fracao& t) {
return ((s.num*t.den)<(s.den*t.num)); }
int operator> (const fracao& s,const fracao& t) {
return ((s.num*t.den)>(s.den*t.num)); }
int operator>= (const fracao& s,const fracao& t) {
return ((s.num*t.den)>=(s.den*t.num));
simplifica();
den=den*t.den;
} }
fracao& fracao::operator= (const fracao& t) //equivale a copy constructor
{
num=t.num; den=t.den; return *this; }
fracao& fracao::operator-= (const fracao& t) {
num=num*t.den-den*t.num; den=den*t.den;
return *this;
//ponteiro para o proprio objeto (o apontado por this) }
fracao& fracao::operator*= (const fracao& t) {
num=num*t.num;
simplifica(); return *this;
fracao& fracao::operator/= (const fracao& t) {
num=num*t.den;
}
fracao::operator double() const
dbl=(double(num)/double(den)); { } { den=den*t.num; simplifica(); return *this; { double dbl; return dbl; }
fracao::operator float() const
float flt;
flt=(float(num)/float(den)); return flt;
fracao::operator long() const
long lng; lng=num/den; return lng;
}
//converte fracao para long
fracao::operator int() const { int ntgr; ntgr=int(num/den); return ntgr; } ---
//programa principal, testes e demonstracao #include <iostream.h> #include "of.h" //definicao da fracao #include <stdio.h> main() { char g;
cout << " Entre com fracao a: "; fracao a,b;
cin >> a;
cout<< "a"<< a << "\n"; cout << " Entre fracao b:"; cin >> b;
fracao c;
cout << "a<=b " << (a<=b)<< "\n"; c=a+b;
cout << "c=a+b " << c << "\n"; fracao d(c);
cout << "fracao d(c)"<< d << endl; //e' o que chamamos de copy constructor cout << "a*b " << (a*b)<< "\n";
cout << "a-b " << (a-b)<< "\n"; cout << "a/b " << (a/b)<< "\n"; cout << "a>b " << (a>b)<< "\n"; cout << "a<b " << (a<b)<< "\n";
cout << "a>=b " << (a>=b)<< "\n"; cout << "a==b " << (a==b)<< "\n"; cout << "a!=b " << (a!=b)<< "\n"; c=a;
a*=b;
cout << "a*=b " << a<< "\n"; a=c;
a/=b;
cout << "a/=b " << a<< "\n"; a=c;
a+=b;
cout << "a+=b " << a << "\n"; a=c;
a-=b;
a=c;
cout << "float(a) " << float(a) << "\n";
--- cout << "long(a) " << long(a) << "\n";
cout << "double(a) " << double(a) << "\n"; cout << "int(a) " << int(a) << "\n";
cin >> g; return 0; }
Resultado do programa: Entre fracao a:9 8 a(9/8) Entre fracao b:9 4 b(9/4) c=a+b (27/8) fraction d(c)(27/8) a*b (81/32) a-b (-9/8) a/b (1/2) a>b 0 a<b 1 a<=b 1 a>=b 0 a==b 0
a-=b (-9/8) a/b (3/10) a!=b 1 a*=b (81/32) a/=b (1/2) a+=b (27/8) long(a) 1 double(a) 1.125 int(a) 1 float(a) 1.125 Resultado do programa: Entre fracao a:1 2 a(1/2) Entre fracao b:5 3 b(5/3) c=a+b (13/6) fraction d(c)(13/6) a*b (5/6) a-b (-7/6) a>b 0 a<b 1 a<=b 1 a>=b 0 a==b 0
a!=b 1 a-=b (-7/6) a*=b (5/6) a/=b (3/10) a+=b (13/6) long(a) 0 double(a) 0.5 int(a) 0 float(a) 0.5 Exercícios:
1)Defina um tipo abstrato de dados matriz (do campo da matemática) com sobrecarga de operadores que permita acessar via índice linear ou linha/coluna qualquer elemento da matriz. Defina outras funções membro que achar importantes. Por herança, construa a classe matriz quadrada, defina a função membro transposta para esta matriz.
Dependendo doas funções membro que você implementar haverá bastante trabalho referente a tratamento de exceções, por exemplo: matrizes singulares não são inversíveis, existem restrições para a multiplicação e até mesmo para a soma e subtração visto que as dimensões nas duas últimas operações tem que ser iguais.