Tag: poo_lab_pt2
composição, agregação, vectores, ficheiros
………..ficha3, exercicio1 (a8)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> using namespace std; //"nao deve ser possivel construir objectos desta classe sem a indicacação.." não pode haver construtor por omissão //"sem desrespeitar o encapsulamento.." gets e sets //"as funções que permitem obter os dados devem poder ser chamadas sobre bjectos constantes" devem conter o const class Ponto { private: //encapsulamento int x; int y; public: //Ponto(int x0, int y0); //necessário introduzir coordenadas ~Ponto(); Ponto(int x0 = 0, int y0 = 0); //construtor por omissão, e) //extra /*Ponto() { x = rand() % 100; y = rand() % 100; cout << "\nponto " << getAsString(); }*/ int getX() const { return x; } void setX(const int x) { this->x = x; } int getY() const { return y; } void setY(const int y) { this->y = y; } double calculaDistancia(const Ponto & outro)const; string getAsString()const; }; Ponto::Ponto(int x0, int y0) { x = x0; y = y0; cout << "\nPonto(in x0, int y0) " << getAsString(); } Ponto::~Ponto() { cout << "\n~Ponto() " << getAsString(); } double Ponto::calculaDistancia(const Ponto& outro) const { //pitágoras, calculo da distância double dist = (x - outro.x) * (x - outro.x) + (y - outro.y) * (y - outro.y); return sqrt(dist); } string Ponto::getAsString() const { ostringstream oss; oss << " ( " << x << " , " << y << " ) " << endl; return oss.str(); } int main() { Ponto a(1,1); Ponto b(2,2); cout << a.getAsString(); //as funções mmebros recebem um ponbteiro para o objectos que as invocou, daí tem acesso a e b cout << a.calculaDistancia(b); //c) const Ponto c(5, 6); //agora só posso chamar funcções que sejam const cout << c.getAsString(); cout << "c.getY(); " << c.getY(); //d) Ponto tab_d[] = {Ponto(1,3), Ponto(2,4), Ponto(5,7)}; //e) Ponto(int x0 = 0, int y0 = 0); //construtor por omissão, e) Ponto tab_e[3]; cout << "\nfim do main" << endl; return 0; }
………..ficha3, exercicio3 (a8, a9)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> using namespace std; //composição de objectos class Ponto { int x; int y; public: //Ponto(); //construtor por omissao //Ponto(int x0, int y0); Ponto(int x0=0, int y0=0); //construtor por omissão Ponto(const Ponto& z); ~Ponto(); int getX() const { return x; } void setX(const int x) { this->x = x; } int getY() const { return y; } void setY(const int y) { this->y = y; } string getAsString() const; }; Ponto::Ponto(int x0, int y0) { x = x0; y = y0; cout << "\nponto(int x0, int y0) " << getAsString(); } Ponto::Ponto(const Ponto& z) { x = rand() % 100; y = rand() % 100; cout << "\nponto(const Ponto& z) " << getAsString(); } Ponto::~Ponto() { cout << "~Ponto()"; } string Ponto::getAsString() const { ostringstream oss; oss << " ponto x" << x << " y " << y << endl; return oss.str(); } class Rectangulo //objecto composto { Ponto canto; int largura; int altura; public: Rectangulo(int x, int y, int largura0, int altura0); Rectangulo(const Ponto& p0, int largura0, int altura0); ~Rectangulo(); Ponto getCanto() const { return canto; } int getX()const { return canto.getX(); } int getY()const { return canto.getY(); } int getLargura() const { return largura; } int getAltura() const { return altura; } bool setLargura(int larg0); bool setAltura(int alt0); void setCanto(const Ponto& c); string getAsString() const; int calculaArea()const; }; Rectangulo::Rectangulo(int x, int y, int largura0, int altura0):canto(x,y) //canto(x,y) membro objecto { if(!setLargura(largura0)) { largura = 1; } if (!setAltura(altura0)) { altura = 1; } cout << "\nrectangulo int x, int y.." << getAsString(); } Rectangulo::Rectangulo(const Ponto& p0, int largura0, int altura0):canto(p0) { cout << "\nrectangulo const Ponto& p0.." << getAsString(); } Rectangulo::~Rectangulo() { cout << "~Rectangulo()" << getAsString(); } bool Rectangulo::setLargura(int larg0) { if(larg0<0) { return false; } largura = larg0; return true; } bool Rectangulo::setAltura(int alt0) { if(alt0<0) { return false; } altura = alt0; return true; } void Rectangulo::setCanto(const Ponto& c) { canto = c; } string Rectangulo::getAsString() const { ostringstream oss; oss << " rectangulo " << canto.getAsString() << " larg: " << largura << " alt: " << altura << endl; return oss.str(); } int Rectangulo::calculaArea() const { return largura * altura; } int main() { //a) relação de composição //b) //Rectangulo a(1, 2, 4, 2); //cout << "\na:" << a.getAsString() << endl; //Rectangulo b(1, 2, 44, 22); //cout << "\nb:" << a.getAsString() << endl; //os cantos são iguais, mas estão localizados em sitios diferentes de memória.. //cada rectangulo tem a posso exclusiva do seu canto. mas são diferentes const Rectangulo c(1, 2, 4, 2); c.getLargura(); cout << "\nfim do main" << endl; return 0; }
………..ficha3, exercicio4 (a9, a10)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> using namespace std; class Ponto { int x; int y; public: //Ponto(); //construtor por omissao //Ponto(int x0, int y0); Ponto(int x0 = 0, int y0 = 0); //construtor por omissão Ponto(const Ponto& z); ~Ponto(); int getX() const { return x; } void setX(const int x) { this->x = x; } int getY() const { return y; } void setY(const int y) { this->y = y; } string getAsString() const; //calcular a distancia entre dois pontos double calculaDistancia(const Ponto& outro)const; bool isIgual(const Ponto& outro)const; }; Ponto::Ponto(int x0, int y0) { x = x0; y = y0; //cout << "\nponto(int x0, int y0) " << getAsString(); } Ponto::Ponto(const Ponto& z) { x = rand() % 100; y = rand() % 100; //cout << "\nponto(const Ponto& z) " << getAsString(); } Ponto::~Ponto() { cout << "~Ponto()"; } string Ponto::getAsString() const { ostringstream oss; oss << " ponto x " << x << " y " << y << endl; return oss.str(); } double Ponto::calculaDistancia(const Ponto& outro) const { //pitágoras, calculo da distância double dist = (x - outro.x) * (x - outro.x) + (y - outro.y) * (y - outro.y); return sqrt(dist); } bool Ponto::isIgual(const Ponto& outro) const { return x == outro.x && y == outro.y; } class Rectangulo //objecto composto { Ponto canto; int largura; int altura; public: Rectangulo(int x, int y, int largura0, int altura0); //Rectangulo(const Ponto& p0, int largura0, int altura0); //Rectangulo(const Rectangulo& r); //construtor por cópia ~Rectangulo(); Ponto getCanto() const { return canto; } int getX()const { return canto.getX(); } int getY()const { return canto.getY(); } int getLargura() const { return largura; } int getAltura() const { return altura; } bool setLargura(int larg0); bool setAltura(int alt0); void setCanto(const Ponto& c); string getAsString() const; int calculaArea()const; }; Rectangulo::Rectangulo(int x, int y, int largura0, int altura0) :canto(x, y) //canto(x,y) membro objecto { if (!setLargura(largura0)) { largura = 1; } if (!setAltura(altura0)) { altura = 1; } //cout << "\nrectangulo int x, int y.." << getAsString(); } //Rectangulo::Rectangulo(const Rectangulo& r) //{ // *this = r; // cout << "\nRectangulo(const Rectangulo& r) " << getAsString() << endl; //} //Rectangulo::Rectangulo(const Ponto& p0, int largura0, int altura0) :canto(p0) //{ // cout << "\nrectangulo const Ponto& p0.." << getAsString(); //} Rectangulo::~Rectangulo() { cout << "~Rectangulo()" << getAsString(); } bool Rectangulo::setLargura(int larg0) { if (larg0 < 0) { return false; } largura = larg0; return true; } bool Rectangulo::setAltura(int alt0) { if (alt0 < 0) { return false; } altura = alt0; return true; } void Rectangulo::setCanto(const Ponto& c) { canto = c; } string Rectangulo::getAsString() const { ostringstream oss; oss << " rectangulo " << canto.getAsString() << " larg: " << largura << " alt: " << altura << endl; return oss.str(); } int Rectangulo::calculaArea() const { return largura * altura; } class Desenho { string nome; vector<Rectangulo> rectangulos; //coleccão de rectangulos //ao ser destruido o vector são destruidos os seus elementos, //são destruidos os rectangulos //existe assim uma relação de composição //relação de posse exclusiva public: Desenho(string nome0); ~Desenho(); void acrescentar(int x, int y, int alt, int larg); //um rectangulo int calculaAreda()const; vector<Rectangulo> pesquisarRectMesmoCanto(const Ponto& p)const; //const, função de consulta, e retorna o conjunto dos rect que satifazem a condição int somaDasAreas()const; int calculaArea()const; string getAsString() const; bool eliminarUm(unsigned int qual); int eliminarRectAreaSup(int areaLimite); }; Desenho::Desenho(string nome0)//:nome(nome0) { //ou nome = nome0; //ou //se nada for indicado, ele vem construido na mesma sendo usada o construtor por omissão } Desenho::~Desenho() { cout << "\n~Desenho" << getAsString(); } void Desenho::acrescentar(int x, int y, int larg , int alt) { Rectangulo rect(x, y, larg, alt); rectangulos.push_back(rect); //é feito uma cópia do rect para o vector, pelo construtor por cópia //ou //rectangulos.push_back(Rectangulo(x, y, larg, alt)); } int Desenho::calculaAreda() const { return 1; } vector<Rectangulo> Desenho::pesquisarRectMesmoCanto(const Ponto& p) const { vector<Rectangulo> v; for(const auto & rect : rectangulos) { //ou if(rect.getCanto().isIgual(p)) { v.push_back(rect); } //ou, mas falha o encapsulamento //pois é a classe do ponto que sabe se dois pontos são iguais //pois quem deve ter a funcionalidade é a classe que tem a informação correspondente //assim não deve ser a classe desenho a faze-lo //if(rect.getCanto().getX() == p.getX() && rect.getCanto().getY() == p.getY()) //{ // v.push_back(rect); //} } return v; } int Desenho::somaDasAreas() const { int soma = 0; //ou for(vector<Rectangulo>::const_iterator it = rectangulos.begin(); it != rectangulos.end(); ++it) { soma += it->calculaArea(); } //ou for(auto it = rectangulos.begin(); it != rectangulos.end(); ++it) { soma += it->calculaArea(); } //ou for(unsigned int i= 0; i< rectangulos.size(); i++) { soma += rectangulos[i].calculaArea(); } //ou for(const auto & elem:rectangulos) { soma += elem.calculaArea(); } return soma; } int Desenho::calculaArea() const { int area = 0; return area; } string Desenho::getAsString() const { ostringstream oss; oss << " nome " << nome << " tem " << rectangulos.size() << " rectangulos \n "; //ou for(unsigned int i = 0; i< rectangulos.size(); i++){ oss << rectangulos[i].getAsString() << endl; } //ou //for( auto & rect : rectangulos) //{ // oss << rect.getAsString() << endl;; //} //ou iteradores //for(vector<Rectangulo>::const_iterator it =rectangulos.begin(); it != rectangulos.end(); ++it) //{ // oss << it->getAsString() << endl; //} return oss.str(); } bool Desenho::eliminarUm(unsigned qual) //qual: indice { { if (qual < 0 || qual >= rectangulos.size()) { return false; } rectangulos.erase(rectangulos.begin() + qual); //o vector auto-reorganiza-se //é um iterator: rectangulos.begin() + qual return true; } } int Desenho::eliminarRectAreaSup(int areaLimite) { //serve para coleções //https://www.cplusplus.com/reference/vector/vector/erase/ int nEliminar = 0; for(vector<Rectangulo>::iterator it = rectangulos.begin(); it != rectangulos.end();) { if(it->calculaArea() > areaLimite) { it = rectangulos.erase(it); ++nEliminar; }else { ++it; } } return nEliminar; //não era necessaria esta informação } int main() { Desenho a1("janela"); cout << "\na1"; a1.acrescentar(1, 2, 3, 4); a1.acrescentar(5, 6, 7, 8); a1.getAsString(); cout << "\nfim do main.." << endl; return 0; }
………..ficha3, exercicio7 (a11, a12)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> #include <fstream> using namespace std; //relação entre banco, conta, pessoa e arquivo de identificacao: //relação entre banco e conta: composição (banco cria a conta) //quando o banco for destruído as contas tambem o são //relação entre conta e pessoa: agregação //relação entre arquivo de identificacao e pessoa: composição (arquivo cria a pessoa) class Pessoa { //objecto dinamico, que não muda. string nome; long bi; long nif; void setBi(long bi); //alteração é privado public: Pessoa(const string& s, long b, long n); Pessoa() = delete; //não disponbilizamos construtor por omissão, fica proibido ~Pessoa(); string getNome() const; void setNome(const string& nome); long getBi() const; long getNif() const; void setNif(const long nif); string getAsString()const; string getDados()const; }; Pessoa::~Pessoa() { cout << "~Pessoa()" << endl; } string Pessoa::getNome() const { return nome; } void Pessoa::setNome(const string& nome) { this->nome = nome; } long Pessoa::getBi() const { return bi; } void Pessoa::setBi(const long bi) { this->bi = bi; } Pessoa::Pessoa(const string& s, long b, long n):nome(s), bi(b),nif(n) { } long Pessoa::getNif() const { return nif; } void Pessoa::setNif(const long nif) { this->nif = nif; } string Pessoa::getAsString() const { ostringstream oss; oss << "nome: " << nome << " bi: " << bi << " nif: " << nif << endl; return oss.str(); } string Pessoa::getDados() const { //ficheiro de dados, linha ostringstream oss; oss << bi << " " << nif << nome << endl; return oss.str(); } class ArquivoDeIdentificacao { //vector de ponteiros para pessoas //ou vector de pessoas/objectos (não ia funcionar bem, porque na conta existe um ponteiro para pessoa, e se for eliminado no arquivo o ponteiro fica como?) //o destrutor tem que destruir primeiro as pessoas, libertar a memória com delete string nome; vector<Pessoa* > pessoas; int pesquisa(long bi)const; public: ArquivoDeIdentificacao(string nome0); ArquivoDeIdentificacao(const ArquivoDeIdentificacao& ob) = delete; //proibir a construção por cópia ArquivoDeIdentificacao& operator=(const ArquivoDeIdentificacao& ob) = delete; //proibir o operador atribuição, proibir a atribuição //esta dupla proibição tem a ver com evitar erros de execuação ~ArquivoDeIdentificacao(); string getNome() const; void setNome(const string& nome); bool acrescentaPessoa(string n, long b, long nif); //relação de posse o arquivo. string getDados()const; //para lidar com ficheiros const Pessoa * getPessoa(long bi); string getAstring()const; bool gravarPessoasEmFicheiroDeTexto(const ArquivoDeIdentificacao &arquivo); bool lerPessoasDeFicheiroDeTexto(ArquivoDeIdentificacao &arquivo); }; int ArquivoDeIdentificacao::pesquisa(long bi) const { //porque existe uma coleção for(unsigned int i = 0; i< pessoas.size(); i++) { if(pessoas[i]->getBi()==bi) { return i; } } return -1; } ArquivoDeIdentificacao::ArquivoDeIdentificacao(string nome0):nome(nome0) { } ArquivoDeIdentificacao::~ArquivoDeIdentificacao() { //o arquivo tem uma relação de composição: cria e destoi a pessoa for(Pessoa * p: pessoas) { cout << p->getAsString(); delete p; } //ou //for (int i = 0; i < pessoas.size(); i++) // delete pessoas[i]; } string ArquivoDeIdentificacao::getNome() const { return nome; } void ArquivoDeIdentificacao::setNome(const string& nome) { this->nome = nome; } bool ArquivoDeIdentificacao::acrescentaPessoa(string n, long b, long nif) { int qual = pesquisa(b); if(qual != -1) { return false; //já existe uma pessoa com este bi } pessoas.push_back(new Pessoa(n, b, nif)); //o arquivo tem uma relação de composição: cria e destoi a pessoa //new Pessoa(n, b, nif) //criar a pessoa em memória dinamica, e retorna o endereço //pessoas.push_back //acrescenta mais um elemento com o endereço da nova pessoa return true; } string ArquivoDeIdentificacao::getDados() const { //para lidar com ficheiros ostringstream oss; for(Pessoa * p: pessoas) { oss << p->getDados() << endl; } return oss.str(); } const Pessoa* ArquivoDeIdentificacao::getPessoa(long bi) //primeiro const: para nao alterar o ponteiro, damos acesso apenas aos dados para onde aponta (read only) { int qual = pesquisa(bi); if(qual == -1) { return nullptr; }else { return pessoas[qual]; } } string ArquivoDeIdentificacao::getAstring() const { ostringstream oss; for(Pessoa * p : pessoas) { oss << p->getAsString(); } return oss.str(); } bool ArquivoDeIdentificacao::gravarPessoasEmFicheiroDeTexto(const ArquivoDeIdentificacao & arquivo) { ofstream dados("dados.txt"); if (!dados.is_open()) { return false; } dados << arquivo.getDados(); dados.close(); if (dados) { return true; } else return false; } bool ArquivoDeIdentificacao::lerPessoasDeFicheiroDeTexto(ArquivoDeIdentificacao& arquivo) { ifstream dados("dados.txt"); string nome; long bi; long nif; string s; if (!dados.is_open()) { return false; } // ler dados de todas as pessoas // uma por linha while (!dados.eof()) { // ler strig com os dados da pessoa getline(dados, s); istringstream iss(s); // ler dados da pessoa iss >> bi >> nif; getline(iss, nome); // se correu bem a leitura ... if (iss) { acrescentaPessoa(nome, bi, nif); } } dados.close(); return true; } class Conta { //ponteiro para pessoa const Pessoa* titular; //const, para não alterar int saldo; public: Conta(const Pessoa* const titular); //posso usar um ponteiro para const ou sem const //ou //Conta(Pessoa* const titular); //pode alterar o apontado desta forma ~Conta(); const Pessoa* getTitular()const; //não altera, damos o conhecimento int getSaldo()const; bool depositar(int quantia); bool levantar(int quantida); long getBi()const; string getAsString()const; }; Conta::Conta(const Pessoa* const titular):titular(titular), saldo(0) { } Conta::~Conta() { cout << "~Conta()" << endl; } const Pessoa* Conta::getTitular() const { return titular; } int Conta::getSaldo() const { return saldo; } bool Conta::depositar(int quantia) { if (quantia <= 0) return false; saldo += quantia; return true; } bool Conta::levantar(int quantia) { if (quantia <= 0 || quantia > saldo) return false; saldo -= quantia; return true; } long Conta::getBi() const { return titular->getBi(); } string Conta::getAsString() const { ostringstream oss; oss << "\ntitular " << titular->getAsString() << "\nsaldo " << saldo << endl; return oss.str(); } class Banco { string nome; //vector de objectos contas vector <Conta> contas; //a destruição deste obejcto vai destruir os membros de outras classes: vector e nome int pesquisar(long bi)const; public: Banco(string n); //~Banco(); //não é preciso, porque as contas não sobrevivem ao fim do banco string getNome() const; void setNome(const string& nome); bool acrescentar(const Pessoa* const pessoa); bool eliminar(long bi); int somaDosSaldos()const; bool depositar(long bi, int quantia); bool levantar(long bi, int quantia); void eliminarTodasAsContas(long bi); string getAsString()const; }; int Banco::pesquisar(long bi) const { for(unsigned int i=0; i< contas.size(); i++) { if(bi == contas[i].getBi()) { return i; } } return -1; } Banco::Banco(string n):nome(n) //vai funcionar o construtor por omissão, e fica vazio, sem lixo/elementos { } //Banco::~Banco() //{ // cout << "\n~Banco" << endl; //} string Banco::getNome() const { return nome; } void Banco::setNome(const string& nome) { this->nome = nome; } bool Banco::acrescentar(const Pessoa* const pessoa) { if (pessoa == nullptr){ return false; } contas.push_back(Conta(pessoa)); //criar contas, é o banco que o faz return true; } bool Banco::eliminar(long bi) { int qual = pesquisar(bi); if(qual == -1) { return false; } contas.erase(contas.begin() + qual); return true; } int Banco::somaDosSaldos() const { int soma = 0; for(const Conta &c : contas) { soma += c.getSaldo(); } return soma; } bool Banco::depositar(long bi, int quantia) { int qual = pesquisar(bi); if(qual == -1) { return false; } return contas[qual].depositar(quantia); } bool Banco::levantar(long bi, int quantia) { int qual = pesquisar(bi); if(qual == -1) { return false; } return contas[qual].levantar(quantia); } void Banco::eliminarTodasAsContas(long bi) //vector { { for (auto it = contas.begin(); it != contas.end();) { if (it->getBi() == bi) { it = contas.erase(it); } else { ++it; } } } } string Banco::getAsString() const { ostringstream oss; oss << "\n== Banco : " << nome << "\t n.contas " << contas.size() << endl; for (unsigned int i = 0; i < contas.size(); i++) { oss << contas[i].getAsString(); } return oss.str(); } int main() { //Pessoa p("coimbra", 123, 321); //cout << p.getAsString(); //Pessoa* ap=nullptr; //ou //Pessoa* const ap = nullptr; //preciso que Conta(const Pessoa* const titular); //ou //const Pessoa* const ap=nullptr; //preciso que Conta(const Pessoa* const titular); //Conta c1(ap); /*Pessoa p1("AAA", 123, 321); Pessoa p2("BBB", 928, 890); Banco b("o banco b"); b.acrescentar(&p1); b.acrescentar(&p2); cout << "Banco \n" << b.getAsString() << endl; b.depositar(123, 40); b.depositar(928, 240); cout << "Bancos depositos\n" << b.getAsString() << endl;*/ //ArquivoDeIdentificacao arquivo("coimbra"); //ArquivoDeIdentificacao arquivo2("porto"); //ArquivoDeIdentificacao arquivo3(arquivo2); //dá erro, proibida a cópia de arquivo2, construção por cópia //arquivo1 = arquivo2; //dá erro, poribida a atribuição , atribuição //arquivo.acrescentaPessoa("pedro", 123, 456); //arquivo.acrescentaPessoa("ines", 888, 999); // //cout << "arquivo de identificacao\n" << arquivo.getAstring(); //ArquivoDeIdentificacao arquivo("coimbra final"); //arquivo.acrescentaPessoa("pedro", 123, 456); //arquivo.acrescentaPessoa("ines", 888, 999); //cout << "arquivo de identificacao\n" << arquivo.getAstring(); // //Banco banco("filial coimbra"); //banco.acrescentar(arquivo.getPessoa(123)); //banco.acrescentar(arquivo.getPessoa(888)); //banco.acrescentar(arquivo.getPessoa(88)); //banco.acrescentar(arquivo.getPessoa(123)); //cout << "banco" << banco.getAsString() << endl; //operação grava ficheiro //ArquivoDeIdentificacao arquivo("coimbra"); //arquivo.acrescentaPessoa("pedro", 123, 456); //arquivo.acrescentaPessoa("ines", 888, 999); //cout << "arquivo de identificacao\n" << arquivo.getAstring(); //Banco banco("filial coimbra"); //banco.acrescentar(arquivo.getPessoa(123)); //banco.acrescentar(arquivo.getPessoa(888)); //banco.acrescentar(arquivo.getPessoa(88)); //banco.acrescentar(arquivo.getPessoa(123)); //cout << "banco" << banco.getAsString() << endl; //arquivo.gravarPessoasEmFicheiroDeTexto(arquivo); //operação ler ficheiro //ArquivoDeIdentificacao arquivo2("porto final"); //arquivo2.lerPessoasDeFicheiroDeTexto(arquivo2); // //cout << "arquivo de identificacao\n" << arquivo2.getAstring(); //Banco banco("filial coimbra"); //banco.acrescentar(arquivo2.getPessoa(123)); //banco.acrescentar(arquivo2.getPessoa(888)); //banco.acrescentar(arquivo2.getPessoa(88)); //banco.acrescentar(arquivo2.getPessoa(123)); //cout << "banco" << banco.getAsString() << endl; cout << "\nfim do main" << endl; return 0; }
Tags : apontamentos, c++11, Learn C plus plus, poo_lab_pt2, poof