classes cujos objectos interagem de forma bidirecional
………..ficha6, exercicio1 (a18)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> #include <fstream> using namespace std; class Aquario; class Peixe { string nomeEspecie; string cor; int peso; int numSerie; int estadio; //0, normal, 1, emagrece, 2,3,4,5 nao come, 6 morre static int sequencia; //constantes iguais para todos: static const int LIMITE_PESO = 50; static const int INICIAL_PESO = 10; public: Peixe(string nomeEspecie0, string cor0="cinzento"); //posso e controlo total: //composição: destrutor a lierbtar os peixes, construtor pro copia e operador atribuição a duplicar aquilo que o destrutor destroi string getNomeEspecie() const; void setNomeEspecie(const string& nome_especie); string getCor() const; void setCor(const string& cor); int getPeso() const; void setPeso(const int peso); int getNumSerie() const; void setNumSerie(const int num_serie); int getEstadio() const; void setEstadio(const int estadio); bool isVivo()const; void alimentar(int quant, Aquario* aquario); string getAsString()const; }; Peixe::Peixe(string nomeEspecie0, string cor0):nomeEspecie(nomeEspecie0), cor(cor0), peso(INICIAL_PESO), numSerie(++sequencia), estadio(0) { } string Peixe::getNomeEspecie() const { return nomeEspecie; } void Peixe::setNomeEspecie(const string& nome_especie) { nomeEspecie = nome_especie; } string Peixe::getCor() const { return cor; } void Peixe::setCor(const string& cor) { this->cor = cor; } int Peixe::getPeso() const { return peso; } void Peixe::setPeso(const int peso) { this->peso = peso; } int Peixe::getNumSerie() const { return numSerie; } void Peixe::setNumSerie(const int num_serie) { numSerie = num_serie; } int Peixe::getEstadio() const { return estadio; } void Peixe::setEstadio(const int estadio) { this->estadio = estadio; } bool Peixe::isVivo() const { return getEstadio() <= 5; } void Peixe::alimentar(int quant, Aquario* aquario) { if(quant <= 0|| aquario == nullptr) { return; } if(estadio >0 && estadio<=5) { ++estadio; return; } if(estadio>5) { return; } peso += quant; if(peso> LIMITE_PESO) { int probabilidade = rand() % 100; if(probabilidade < 50) { peso = LIMITE_PESO - INICIAL_PESO; aquario->nasceNovoPeixe(nomeEspecie, cor); }else { peso /= 2; //reduzido a metade estadio = 1; } } } string Peixe::getAsString() const { ostringstream oss; oss << "\nPeixe: " << nomeEspecie << "\ncor: " << cor << "\npeso: " << peso << "\nnumSerie: " << numSerie << (estadio <= 5 ? " vivo" : " morto") << " estadio " << estadio << endl; return oss.str(); } int Peixe::sequencia = 499; //num. para cada peixe //relação bidirecional entre o Peixe e o Aquario //include no CPP e declaração da classe no h class Aquario { //tem uma colecção de peixes vector<Peixe*> peixes; vector<Peixe*> novos; //o peixe usa para colocar os novos void eliminarMortos(); void deslocaNovoParaAquario(); int pesquisaPeixe(int numSerie0)const; public: Aquario() = default; //os dois vectores são construidos por omissão, isto é ficam vazios na construção //e porque não existe nenhum ponteirp primitivo na classe //e no construtor por copia fica mais simples virtual ~Aquario(); //quando um peixei e colocado no aquario, este assume //a sua posse e controlo total: Aquario(const Aquario& orig); //construtor por copia Aquario& operator=(const Aquario & orig); //operador atribuição void removePeixe(int numSerie); void alimentar(int quantidade0); void nasceNovoPeixe(string especie0, string cor0); bool acrescentaPeixeDoExterior(Peixe* peixe); string getAsString()const; }; void Aquario::alimentar(int quantidade0) { for(Peixe * p : peixes) { p->alimentar(quantidade0, this); //mt cuidado com isto, usa o vector<Peixe*> novos; } eliminarMortos(); deslocaNovoParaAquario(); //sair do novo para o aquario normal } void Aquario::nasceNovoPeixe(string especie0, string cor0) { novos.push_back(new Peixe(especie0, cor0)); } bool Aquario::acrescentaPeixeDoExterior(Peixe* peixe) { if (peixe == nullptr){ return false; } //se o peixe estiver no aquario if(pesquisaPeixe(peixe->getNumSerie())!= -1) { return false; } //se ainda nao esta no aquario //criar um novo em mem dinamica, com new Peixe* p = new Peixe(*peixe); //faço copia local peixes.push_back(p); return true; } string Aquario::getAsString() const { ostringstream oss; oss << "\nAquario; " << endl; for(Peixe * p: peixes) { oss << p->getAsString(); } return oss.str(); } int Aquario::pesquisaPeixe(int numSerie0)const { for(int i=0; i < peixes.size(); i++) { if(peixes[i]->getNumSerie() == numSerie0) { return i; } } return -1; } void Aquario::eliminarMortos() { //formula //ou //for(vector<Peixe*>::iterator it = peixes.begin() ; it != peixes.end(); ) //ou for(auto it = peixes.begin(); it != peixes.end();) { if(!(*it)->isVivo()) { delete (*it); it = peixes.erase(it); }else { ++it; } } } void Aquario::deslocaNovoParaAquario() { for(Peixe * p: peixes) { peixes.push_back(p); } novos.clear(); } Aquario::~Aquario() { for(Peixe * p: peixes) { delete p; } for(Peixe * p: novos) { delete p; } cout << "\n~Aquario()" << endl; } Aquario::Aquario(const Aquario& orig) { *this = orig; } Aquario& Aquario::operator=(const Aquario& orig) { //prevenção da auto atribuição if(this == &orig) { return *this; } //libtertar mem dina velha for(Peixe * p : peixes) { delete p; } peixes.clear(); //copiar a infor de orig, duplicando os objectos dinamicos Peixe for(Peixe * p: orig.peixes){ peixes.push_back(new Peixe(*p)); } for(Peixe * p: orig.peixes) { novos.push_back(new Peixe(*p)); } return *this; } void Aquario::removePeixe(int numSerie) { int qual = pesquisaPeixe(numSerie); if(qual == -1) { return; } delete peixes[qual]; peixes.erase(peixes.begin() + qual); } int main() { Peixe a("Robalo", "branco"); Peixe b("Pescada"); Peixe c("Salmao"); Aquario* aq1 = new Aquario; aq1->acrescentaPeixeDoExterior(&a); aq1->acrescentaPeixeDoExterior(&b); aq1->acrescentaPeixeDoExterior(&c); cout << aq1->getAsString() << endl; // peso 10 aq1->alimentar(20); cout << aq1->getAsString() << endl; // peso 30 aq1->alimentar(30); cout << aq1->getAsString() << endl; // peso 60 e consequencias for (int i = 0; i < 6; ++i) { aq1->alimentar(1); cout << aq1->getAsString() << endl; } aq1->removePeixe(500); aq1->removePeixe(500); cout << aq1->getAsString() << endl; /// testa mem din Aquario* aq2 = new Aquario; aq2->acrescentaPeixeDoExterior(&a); aq2->acrescentaPeixeDoExterior(&a); aq2->acrescentaPeixeDoExterior(&a); cout << aq2->getAsString() << endl; *aq2 = *aq1; delete aq1; cout << " aq1:\n"; cout << " aq2:\n"; cout << aq2->getAsString() << endl; Aquario* aq3 = new Aquario(*aq2); delete aq2; cout << aq3->getAsString() << endl; delete aq3; cout << "\nfim do main" << endl; return 1; }
Tags : apontamentos, c++11, Learn C plus plus, poo_lab_pt5, poof
0 thoughts on “classes cujos objectos interagem de forma bidirecional”