Tag: poo_lab_pt5
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