operadores
………..ficha4, exercicio1 (a13, a14)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> #include <fstream> using namespace std; //os operadores //uso de operados de atribuiçao em situações de composição envolvendo memória dinâmica //aumentar a clareza do código por exemplo a.multiplica(b) po a * b //operadores podem ser globais ou membros //p.e.: globaL operator++(a,b) //p.e.: membro a.operator++(b) /* +---------------------------------------- + -------------------------- - + | operador membro / não membro | +---------------------------------------- + -------------------------- - + | todos os operadores unários p.e: ++a, a++ | membro | | = () -> ->* | têm sempre que ser membro | | += -= /= *= &= |= %= >>= <<= | membro | | todos os restantes operadores binários, ==,<<... | globais | +---------------------------------------- + -------------------------- - + */ //o retorno de um operador pode ser um valor ou uma cópia de algo //se o objectivo é usar o resultado de um operador, então este deve ser uma referência para algo, não constante e que pode ser modificado class Fraccao { int numerador; int denominador; public: //explicit //se usado trancamos o construtor, fazendo com que tenhamos que usar implicitamente Fracca(a) , na main //explicit, indicar ao construtor que só trabalhar quando o mandarmos trabalhar Fraccao(); Fraccao(int num); Fraccao(int num, int denom); int getNumerador() const; void setNumerador(const int numerador); int getDenominador() const; void setDenominador(const int denominador); string getAsString() const; //b v3 Fraccao operator*(const Fraccao& f); //operador * membro //j) Fraccao & operator*=(const Fraccao& f); //operador *= membro, não pode ser void //m) membro, operador unário Fraccao & operator++(); //++a Fraccao operator++(int n); //a++, int n, serve para poderem funcionar as duas, mesmo que nao faça nada //n) passamos uma fraccao mas a f recebe apenas um inteiro //operador de conversao operator int()const { return denominador/numerador; }; }; Fraccao::Fraccao() { numerador = 0; denominador = 1; } Fraccao::Fraccao(int num) :numerador(num) { denominador = 1; } Fraccao::Fraccao(int num, int denom):numerador(num) { setDenominador(denom); } int Fraccao::getNumerador() const { return numerador; } void Fraccao::setNumerador(const int numerador) { this->numerador = numerador; } int Fraccao::getDenominador() const { return denominador; } void Fraccao::setDenominador(const int denominador) { if(denominador >0) { this->denominador = denominador; }else if(denominador ==0) { this->denominador = 1; }else { this->numerador = -this->numerador; this->denominador = -denominador; } } string Fraccao::getAsString() const { ostringstream oss; oss << " ( " << numerador << " / " << denominador << " ) " << endl; return oss.str(); } //b, v3 Fraccao Fraccao::operator*(const Fraccao& f) { cout << "operator*(const Fraccao& f)\n"; Fraccao prod(getNumerador() * f.getNumerador(), getDenominador() * f.getDenominador()); return prod; } Fraccao & Fraccao::operator*=(const Fraccao & f) { cout << "operator*=(const Fraccao & f)\n"; numerador *= f.getNumerador(); denominador *= f.getDenominador(); return *this; } Fraccao& Fraccao::operator++() { numerador += denominador; //a fracao aumenta uma unidade return *this; //retorna objecto depois de incremento } Fraccao Fraccao::operator++(int n) { Fraccao aux = *this; //grava para esta varavel auxiliar o objecto antes de incrementar numerador += denominador; //a fracção aumenta uma unidade return aux; //não pode ser por referencia, retorna-se a variavel local } //b, v1 Fraccao produto(const Fraccao& x, const Fraccao& y) //função global { Fraccao prod(x.getNumerador() * y.getNumerador(), x.getDenominador() * y.getDenominador()); return prod; } //b, v2 Fraccao operator*(const Fraccao& x, const Fraccao& y) //função global { cout << "operator*(const Fraccao& x, const Fraccao& y)\n"; Fraccao prod(x.getNumerador() * y.getNumerador(), x.getDenominador() * y.getDenominador()); return prod; } //g ostream & operator<<(ostream & saida, const Fraccao & ob) { saida << ob.getAsString(); return saida; } //extra istream& operator>>(istream& entrada, Fraccao& ob) { int num, denom; entrada >> num, denom; if(entrada) { ob.setNumerador(num); ob.setDenominador(num); } return entrada; } //n) void func(int n) { cout << n; // aparece 2 } //o) (a==b) bool operator==(const Fraccao& op1, const Fraccao& op2); bool operator==(const Fraccao& op1, const Fraccao& op2) { return (op1.getNumerador() * op2.getDenominador() == op1.getDenominador() * op2.getNumerador()); } int main() { //a) /*Fraccao a(1, 2); Fraccao b(3); const Fraccao c(3, 4); cout << a.getAsString(); cout << b.getAsString(); cout << c.getAsString();*/ //b) multiplicação de duas fraccoes //v1 //Fraccao a(1, 2); //Fraccao b(3); //const Fraccao c(3, 4); //Fraccao a1; //a1 = produto(b,c); //cout << a1.getAsString(); //v2 //a = b * c; // a = operator(b,c); global //cout << a.getAsString(); //v3 (estando as duas opções disponiveis, global ou membro, recai sobre o membro) //a = b * c;// a = b.operator*(c); membro //cout << a.getAsString(); //c) //Fraccao a(1, 2); //Fraccao b(3); //const Fraccao c(3, 4); //a = a * b * c; //composição das funções, (a*b)*c //operator*(operator*(a,b),c) //cout << a.getAsString(); //d e e) //Fraccao a(1, 2); //Fraccao b(3); //a = b * 4; //b.operator*(4) //cout << a.getAsString(); //d e e) v2 construtor explicit //a = b * Fraccao(4); //só assim funcionaria //d e e) v3 //Fraccao a(1, 2); //Fraccao b(3); //a = 4 * b; //funciona apenas o global, se for membro só se usado o explicit, Fraccao(4) * b; //cout << a.getAsString(); //g) v1 //Fraccao a(1, 2); //cout << a; //<<, operador binário, tem que ser operador global //cout está a invocar a nossa operação, cout é da classes ostream, não é da nossa classe, logo << tem que ser global //g e h) v2 //Fraccao a(1, 2); //Fraccao b(3); //const Fraccao c(3, 4); //cout << a << b << c; //por ser global e ostream ao inves de void funciona em cadeia //i) ao inves de copia usar o valor, ostream & operator<<(ostream saida, const Fraccao & ob) //não dá...dá erro //extra //Fraccao a(1, 2); //Fraccao b(3); //cin >> a; //cout << a.getAsString(); //j) a *= b //Fraccao a(1, 2); //Fraccao b(2,3); ////a *= b; ////operador global: operator*=(a,b) ////operador membro: a.operator*=(b) //recomendada ////*= te como retorno //cout << "antes->" << " a: " << a << " b: " << b << endl; //a *= b; //cout << "depois->" << " a: " << a << " b: " << b << endl; //Fraccao a2(1, 2); //Fraccao b2(2, 3); //Fraccao c2(3, 4); //cout << "antes->" << " a2: " << a2 << " b2: " << b2 << " c2: " << c2 << endl; //a2 *= b2 *= c2; //cout << "depois->" << " a2: " << a2 << " b2: " << b2 << " c2: " << c2 << endl; //Fraccao a3(1, 2); //Fraccao b3(2, 3); //Fraccao c3(3, 4); //cout << "antes->" << " a3: " << a3 << " b3: " << b3 << " c3: " << c3 << endl; //(a3 *= b3) *= c3; //cout << "depois->" << " a3: " << a3 << " b3: " << b3 << " c3: " << c3 << endl; //l) retornar referencia ou valor //Fraccao a(1, 2), b(2, 3), c(3, 4); //cout << "antes->" << " a: " << a << " b: " << b << " c: " << c << endl; //(a *= b) *= c; //cout << "depois->" << " a: " << a << " b: " << b << " c: " << c << endl; //// é suposto aparecer 6/24 //cout << a; //cout << "expressao ((a *= b) *= c)" << ((a *= b) *= c) << endl; //retornar por referência Fraccao & Fraccao::operator*=(const Fraccao & f) //retornar por valor (é uma copia) Fraccao Fraccao::operator*=(const Fraccao & f) //m) posfixado, a++ e prefixado ++a //++a, global, operator++(a) //++a, membro, a.operator++() //não recebe nenhum argumento //prefixado //int n = 2; //cout << "++n= " << ((++n)) << endl; //3, e é possivel fazer uma atribuição (++n)=55, vem ++n=55 //cout << " n= " << n << endl; //3 ////posfixado //int n2 = 2; //cout << "n2++= " << ((n2++)) << endl; //2 //cout << " n2= " << n2 << endl; //3 //Fraccao a(1, 2), b(2, 3), c(3, 4); //(++a) = c; //cout << ++a; //a.operator++() //sem argumento //cout << a; //Fraccao a2(1, 2), b2(2, 3), c2(3, 4); //cout << a2++; //a.operator++(0) //0 é um argumento //cout << a2; //n) //const Fraccao f(7,3); //func(f); // é passado automaticamente o valor 7/3 // // arredondado para baixo //o) if(a==b) //tem que existir o operador== que retorne um bool, e é global Fraccao a(1, 2), b(1, 2); if(a== b) { cout << "oi"; }else { cout << "noi"; } cout << "\nfim do main" << endl; return 0; }
………..ficha4, exercicio3 (a14)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> #include <fstream> using namespace std; /* +---------------------------------------- + -------------------------- - + | operador | membro / não membro | +---------------------------------------- + -------------------------- - + | todos os operadores unários p.e: ++a, a++ | membro | | = () -> ->* | têm sempre que ser membro | | += -= /= *= &= |= %= >>= <<= | membro | | todos os restantes operadores binários, ==,<<... | globais | +--- */ class Automovel { const string matricula; //const para proibir atribuições string marca; string modelo; int ano; static int nAutomoveisCriados; //tem que ser inicializada fora da classe public: Automovel(const Automovel& ob); Automovel(string matricula, string marca, string modelo, int ano); ~Automovel(); string getMatricula()const; string getMarca()const; string getModelo()const; int getAno()const; static int getNAutomoveisCriados(); void setMarca(string marca); void setModelo(string modelo); void setAno(int ano); string getAsString()const; Automovel& operator=(const Automovel& ob); //retorna uma referencia para o primeiro membro da atribuição }; int Automovel::nAutomoveisCriados = 0; ostream& operator<<(ostream& saida, const Automovel& ob); Automovel::Automovel(const Automovel& ob):matricula(ob.matricula), marca(ob.marca), modelo(ob.modelo), ano(ob.ano) { cout << "\nConstrutor por copia"; ++nAutomoveisCriados; //tambem por copia, os construidos por cópia tb devem ser contados! } Automovel::Automovel(string matricula1, string marca1, string modelo1, int ano1): matricula(matricula1), marca(marca1), modelo(modelo1), ano(ano1) { cout << "\nConstrutor com parametros"; ++nAutomoveisCriados; } Automovel::~Automovel() { cout << "\nDestruindo " << getAsString(); } string Automovel::getMatricula()const { return matricula; } string Automovel::getMarca()const { return marca; } string Automovel::getModelo()const { return modelo; } int Automovel::getAno()const { return ano; } int Automovel::getNAutomoveisCriados() { return nAutomoveisCriados; } void Automovel::setMarca(string marca1) { marca = marca1; } void Automovel::setModelo(string modelo1) { modelo = modelo1; } void Automovel::setAno(int ano1) { ano = ano1; } string Automovel::getAsString()const { ostringstream oss; oss << "\nAutomovel: " << matricula << " " << marca << " " << modelo << " " << ano; return oss.str(); } Automovel& Automovel::operator=(const Automovel& ob) { // if (this == &ob) { return *this; } cout << "\nOperador atribuicao "; //a matricula nao se altera no objecto destino da atribuição this->marca = ob.marca; this->ano = ob.ano; this->modelo = ob.modelo; return *this; } ostream& operator<<(ostream& saida, const Automovel& ob) { saida << ob.getAsString() << endl; return saida; } void f(Automovel x) { cout << x << endl; } int main() { Automovel a1("11-11-AA", "OPEL", "OMEGA", 2010); Automovel a2("22-22-BB", "FIAT", "PUNTO", 2011); Automovel a3 = a1; //a3 copia de a1, construtor por copia a1 = a2; //operador atribuição, mas havendo membros constantes, tem que se fazer o operador operator= //a1.operator=(a2) f(a1); return 1; }
Tags : apontamentos, c++11, Learn C plus plus, poo_lab_pt3, poof
0 thoughts on “operadores”