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 : , , , ,

0 thoughts on “operadores”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.