Tag: poo_lab_pt1
Encapsulamento, classes, construtores, destrutores
………..ficha2, exercicio3e4 (a4,a5)
#include <string> #include <iostream> #include <sstream> #include <vector> using namespace std; class Caderno { private: //membros variáveis string marca; string cor; int numFolhas; string tamanho; public: Caderno(const string& marca, const string& cor, const int num_folhas, const string& tamanho) //const não consigo alterar o argumento que vem da main, assim fica mais eficiente/seguro, //e tambem assim posso fazer uso de uma const, usando por exemplo "marca" //o int pode ter const ou não e referencia, e porque é uma coisa pequena : marca(marca), cor(cor), numFolhas(num_folhas), tamanho(tamanho) { } //membros funções //funções get //os consts sigificam que não podem alterar nada, é uma função de consulta string getMarca() const { return marca; } string getCor() const { return cor; } int getNumfolhas() const { return numFolhas; } string getTamanho() const { return tamanho; } //funções set void setMarca(const string & marca) { this->marca = marca; } void setCor(const string & cor) { this->cor = cor; } void setNumfolhas(int num_folhas) { if(num_folhas>0){ numFolhas = num_folhas; }else { numFolhas = 0; } } void setTamanho(const string& tamanho) { this->tamanho = tamanho; } string getAsString()const; }; string Caderno::getAsString()const { ostringstream oss; oss << "\nmarca: " << marca << "\ncor: " << cor << "\nnum folhas: " << numFolhas << "n\ntamanho: " << tamanho; return oss.str(); } int main() { const Caderno Cad1("bic","branca",2,"a4"); //const não posso alterar cout << Cad1.getAsString(); cout << "\nfim do main" << endl; return 0; }
………..ficha2, exercicio5 (a5)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> using namespace std; class Automovel { private: string matricula; string combustivel; string marca; string modelo; int ano; static int conta; //não surge nos objectos, surge fora dos objectos, membro estático //e vai precisar de ser inicializado, no inicio e surge int Automovel::conta = 0; //validar a matricula do automovel bool validaMatricula(const string & s) const ; public: Automovel(const string& matricula, const string& combustivel, const string& marca, const string& modelo, const int ano) : combustivel(combustivel), marca(marca), modelo(modelo) //o ano nao surge aqui fica com lixo { setMatricula(matricula); //construida por omissão setAno(ano); //construida por omissão ++conta; } string getMatricula() const { return matricula; } string getCombustivel() const { return combustivel; } string getMarca() const { return marca; } string getModelo() const { return modelo; } int getAno() const { return ano; } static int getConta(); void setMatricula(const string & matricula) { if(validaMatricula(matricula)){ this->matricula = matricula; } //this->matricula = "99-AA-99"; } void setCombustivel(const string& combustivel) { this->combustivel = combustivel; } void setMarca(const string& marca) { this->marca = marca; } void setModelo(const string& modelo) { this->modelo = modelo; } void setAno(const int ano) { if (ano > 2000 && ano < 2021) { this->ano = ano; } else { this->ano = 0; } } string getAsString()const; }; int Automovel::conta = 0; //vai ser criado logo no inicio do main int Automovel::getConta() { return conta; } string Automovel::getAsString()const { ostringstream oss; oss << "\nmatricula: " << matricula << "\ncombustivel: " << combustivel << "\nmarca: " << marca << "n\\nmodelo: " << modelo << "\nano: " << ano; return oss.str(); } bool Automovel::validaMatricula(const string & s) const { //v1 //if (s.length() != 8) //{ // return false; //} //return true; //v2 expressões regulares string patern = "((\d{2}-\d{2}-[A-Z]{2}) | (\d{2}-[A-Z]{2}-\d{2}) | (\[A-Z]{2}-\d{2}-\d{2}))"; //string patern = R"((\d{2}-\d{2}-[A-Z]{2}) | (\d{2}-[A-Z]{2}-\d{2}) | (\[A-Z]{2}-\d{2}-\d{2}))"; //string patern = R"(([A-Z]{2}-\d{2}-(\d{2}|[A-Z]{2}))|(\d{2}-(\d{2}-[A-Z]{2}|[A-Z]{2}-\d{2})))"; regex reg(patern); if(regex_match(s, reg)) { return true; } return false; } int main() { cout << "\nconta: " << Automovel::getConta() << endl; Automovel A1("11-22-CD", "gasolina", "opel", "corsa", 2020); cout << A1.getAsString(); cout << "\nconta: " << Automovel::getConta() << endl; cout << "\nfim da main"; return 0; }
………..ficha2, exercicio7 (a6,a7)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> using namespace std; class MSG { private: char letra; int numero; static int contador; //MSG(const MSG& ob); //i) public: MSG(char letra = 'X'); //por valor por omissão, um constutor por omissão //MSG(char letra); //alternativa que tb funcionar a aliena e) ~MSG(); //construtor por cópia MSG(const MSG& ob); char getLetra() const { return letra; } void setLetra(const char letra) { this->letra = letra; } int getNumero() const { return numero; } void setNumero(const int numero) { this->numero = contador; } string getAsString() const; }; int MSG::contador = 0; MSG::MSG(char letra) { this->letra = letra; this->numero = ++contador; cout << "\ncriado: " << getAsString() << endl; } MSG::~MSG() { cout << "\nterminado: "<< getAsString() << endl; } //construtor por cópia c) MSG::MSG(const MSG& ob) { //anular o construtor por cópia por defeito que é fornecido pelo compilador letra = ob.letra; numero = -ob.numero; //para fazer uma coisa diferente (numero simétrico) cout << "\nCriado por copia " << getAsString(); } string MSG::getAsString() const { ostringstream oss; oss << "\nletra " << getLetra() << " numero " << getNumero() << endl; return oss.str(); } void teste_g() { MSG aux('y'); } void teste_h(MSG z) { //h) //a passagem de um objecto como parametro por valor (funcionou o construtor por cópia) //(z é copia de b, e funciona o construtor por cópia) } void teste_l(MSG & z) //passar o objecto por referencia { //l) //uma referencia não tem o seu lugar proprpio, vai ser apenas outro nome para b, //z coincide em memoria com b, não surge outro objecto, é apenas outro nome //constutor e destrutor são os mesmos } MSG teste_m() { MSG m; //é criado localemnte um objecto m return m; //retornar o m por valor } MSG & teste_n() //retorno por referencia, para uma variavel que já existe { MSG m; //é criado localemnte um objecto m return m; //retornar o m com estatuto de referencia ( não existe uma cópia ) } int main() { //objectos não dinamicos, que vai ser destruido no fim do main //MSG m1('a'); //MSG m2; //para fazer uso do default //objectos dinâmicos //MSG* p = new MSG('D'); //cout << "\n vou construir D"; //delete p; //destruo o objecto apontado por p, destruido expressamente //cout << "\n vou destruir D"; //MSG & m3 = m2; //alinea b) //m3 é uma referência que se vai "colar" a m2, m3 é um outro nome para m2 //não vai ser criado mais nenhum objecto //c) //MSG m4 = m2; //não existe nenhum construtor por cópia implementado //mas funionou um //todas as classe que não tenham um construtor por cópia, o compilador fornece um //a nossa construção do construtor por cópia //MSG m4 = m2; //criado por cópia //d) atribuição //MSG m4 = m2; //criado por cópia //m1 = m2; //atribuição //e) matriz (array) de objectos //MSG mat1[] = {'M', 'N'}; //f) matriz (array) de objectos //MSG mat2[2]; //criado se e só existir um constutor por omissão //ou //MSG m1('a'); //MSG m2; //para fazer uso do default //MSG mat[] = { m1, m2 }; //ou //MSG mat[4] = { MSG('A') , MSG('B') }; //ou //MSG mat[4] = { MSG() , MSG() }; //g) /*cout << "\n alinea g)" << endl; teste_g(); cout << "\n alinea g)" << endl; teste_g();*/ //h) //MSG b; //cout << "\n alinea h)" << endl; //teste_h(b); //cout << "\n alinea h)" << endl; //teste_h(MSG('c')); //a passagem de um objecto como parametro por valor (funcionou o construtor por cópia) //(z é copia de b, e funciona o construtor por cópia) //i) e j) //em privado o construtor po cópia MSG(const MSG & ob); //mas sendo privado a cópia não vai funcionar, teste_h(b); //k) //objecto é criado com lixo, e é bloqueada a construção por cópia do compilador //l) /*MSG b; teste_l(b);*/ //m) //MSG b = teste_m(); //o valor m chegou aqui //, mas m perde a validade no primeiro }, morre aqui, é terminado //vai ser feita uma copia de m e é este que vai representar a informação a seguir ao = do teste_m() //quem actua é o construtor por cópia, o return é uma cópia //n) retorno por referência MSG b = teste_n(); // cout << "\nfim do main" << endl; return 0; }
………..ficha2, exercicio9 (a7, a8)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> using namespace std; class Televisao { vector<string> canais; //estes endereços podem mudar de sítio //acrescentar elementos ao canais.push_back("rtp1"); //string s = "sic"; //canais.push_back(s); //percorrer: //for(int i = 0; i< canais.size(); i++){ // cout << canais[i]; //} //esvaziar tudo: //canais.clear(); //size a zero //alternativa será uso de vectores de ponteiros para objectos dinâmicos (dinâmicos vão estar no seu lugar) bool ligada; int volume; int canal; //indice do vector de canais +1 string nomeCanal; //o conjunto de canais definido na construção não se altera a partir do exterior da classe void setCanais(string canais0[], unsigned int n); public: Televisao(string canais0[], int n); bool isLigada()const; //is por ser booleana void ligar(); void desligar(); void aumentaVolume(); void diminuiVolume(); void mudaCanal(int c); int getCanal() const { return canal; } //para experimentar Televisao(initializer_list<string> canais0); //lista de constantes, separadas por virgulas e chavetas void setCanais(initializer_list<string> canais0); void setCanais2(vector<string> canais0); string getAsString()const; }; void Televisao::setCanais(string canais0[], unsigned int n) { //validação if(n< 0) { n = 0; } //se já tiver previamente preecnhido canais.clear(); for(unsigned int i = 0; i < n; ++i) { canais.push_back(canais0[i]); //copiar os elementos para o vector de strings } } Televisao::Televisao(string canais0[], int n) { setCanais(canais0, n); ligada = false; volume = 0; canal = 1; cout << "\nNormal" << endl; } bool Televisao::isLigada() const { return ligada; } void Televisao::ligar() { ligada = true; } void Televisao::desligar() { ligada = false; } void Televisao::aumentaVolume() { if (ligada != true) return; if (volume <= 10) volume++; } void Televisao::diminuiVolume() { if (ligada != true) return; if (volume >= 10) volume--; } void Televisao::mudaCanal(int c) { if (ligada != true) return; unsigned cc = c; if (cc > 0 && cc <= canais.size()) canal = c; } Televisao::Televisao(initializer_list<string> canais0) { setCanais(canais0); ligada = false; volume = 0; canal = 1; cout << "\nInitializer" << endl; } void Televisao::setCanais(initializer_list<string> canais0) { canais.clear(); //ou //for (const auto& c : canais) //{ // canais.push_back(c); //} //ou //for (initializer_list<string>::iterator it = canais0.begin(); it != canais0.end(); ++it){ // canais.push_back(*it); //} //ou for(auto it = canais0.begin(); it != canais0.end(); ++it) { canais.push_back(*it); } } void Televisao::setCanais2(vector<string> canais0) { canais.clear(); for (auto it = canais0.begin(); it != canais0.end(); ++it) { canais.push_back(*it); } } string Televisao::getAsString() const { ostringstream oss; //for(unsigned int i = 0; i < canais.size() ; ++i) //{ // //oss << canais[i] << " "; // oss << canais.at(i) << " "; //} //for (const string& c : canais) //c é um outro nome para cada um dos elementos da coleção // oss << c << " "; //for (string c : canais) //c é uma copia dos elementos da coleção // oss << c << " "; //for (const auto & c : canais) // oss << c << " "; //iterador aponta para os elementos do objecto e desta forma conseguimos percorrer //for (vector<string>::const_iterator it = canais.begin(); it != canais.end(); ++it) // oss << *it << " "; for( auto it = canais.begin() ; it != canais.end(); ++it) { oss << *it << " "; } if(!ligada) { oss << "desligada\n"; return oss.str(); } if(canais.empty()) { oss << "sem canais "; return oss.str(); } oss << "\nCanal" << canais[canal-1] << " " << canal << "\nvolume: " << volume << endl; return oss.str(); } int main() { //exemplos dos inicializer lists Televisao tv = { "um","dois","tres","quatro" }; Televisao tv2{ "um", "dois" }; Televisao tv3({ "um","dois" }); //outro exemplo e se for construtor e fizer uso dos () tv.setCanais2({ "um","dois","tres" }); //uniform inicialization //usar estes construtor Televisao(string canais0[], int n); string canais[] = { "um","dois" }; Televisao tv4(canais, 2); Televisao tv5{ canais, 2 }; Televisao tv6 = { canais, 2 }; cout << "\nfim do main" << endl; return 0; }
………..ficha2, exercicio5 (a10, a11)
#include <string> #include <iostream> #include <sstream> #include <vector> #include <regex> #include <initializer_list> using namespace std; class Prego { int x, y; public: Prego(int a, int b); ~Prego(); void mudaDeSitio(int a, int b); string getAsString() const; int getX()const { return x; } int getY()const { return y; } }; Prego::Prego(int a, int b):x(a), y(b) { //x = a; y = b; cout << "construindo prego em " << x << "," << y << "\n"; } Prego::~Prego() { cout << "~Prego em " << x << "," << y << "\n"; } void Prego::mudaDeSitio(int a, int b) { x = a; y = b; } string Prego::getAsString() const { ostringstream oss; oss << "Prego: ( " << x << " , " << y << " ) "; return oss.str(); } class Aviso { string texto; //Prego prego; //relação de composição. //Prego * prego; //usamos um ponteiro, já não é uma posse exclusiva //aviso é destruído, o prego fica lá.. //com ponteiro pode haver posse excluiva ou não //Prego * const prego; //não é possivel mudar o endereço do prego //recebe um valor e não pode mudar, usa-se o const const Prego * const prego; //O aviso nao te direito a fazer alterações ao Prego... const Prego //a relação entre aviso e prego é de agregação (tem o conhecimento) //porque se o aviso for destruido o prego não é //o prego pode ser partilhado por mais de um aviso //o prego já existe antes do aviso //o aviso tem o conhecimento do prego public: Aviso(const string & t, const Prego * const p); ~Aviso(); int getX() const; int getY() const; string getAsString() const; Aviso(const Aviso& ob); //construtor por cópia }; Aviso::Aviso(const string& t, const Prego * const p):texto(t), prego(p) { //prego = p //nao é possivel usar porque o Prego é um membro constante de Aviso (ou até podia ser uma referencia) //logo tem que ser usada a outra opção //os membros const e os membros referencias é obrigatório inicializar na lista de inicialização do construtor cout << " construido Aviso " << texto << endl; } Aviso::~Aviso() { cout << " ~Aviso() " << texto << endl; } int Aviso::getX() const { return prego->getX(); } int Aviso::getY() const { return prego->getY(); } string Aviso::getAsString() const { ostringstream oss; oss << "Aviso: " << texto << " " << prego->getAsString(); return oss.str(); } Aviso::Aviso(const Aviso& ob):prego(ob.prego) { texto = ob.texto+"Copia"; cout << "CCopia de aviso " << texto << endl; } int main() { Prego p(1, 2); Aviso a("quadro 1", &p); Aviso b("quadro 2", &p); cout << " A " << a.getAsString() << endl; cout << " B " << b.getAsString() << endl; p.mudaDeSitio(99, 99); cout << " A " << a.getAsString() << endl; cout << " B " << b.getAsString() << endl; //a=b; //erro //a atribuição entre dois objectos é feita membro a membro //o texto consegue atribuir, mas o prego pk tem const não consegue //assim a atribuição default dá erro, podemos é usar uma atribuição que funcione //usando o operador atribuição Aviso c = a; cout << " C " << c.getAsString() << endl; vector<Aviso> avisos; cout << "-pushback-\n"; avisos.push_back(a); Aviso* pa = &avisos[0]; //ponteiro para o primeiro elemento do vector cout << pa->getAsString() << endl; avisos.push_back(b); Aviso* pb = &avisos[0]; cout << pb->getAsString() << endl; if(pa==pb) { cout << " == \n"; }else { cout << " != \n"; } cout << avisos[0].getAsString() << endl; //avisos.erase(avisos.begin() + 1); //dá erro, pk os objectos do vector têm um membro constante //a atribuição dá erro, e o erase precisa de atribuições internamente cout << "\nfim do main" << endl; return 0; }
Tags : apontamentos, c++11, Learn C plus plus, poo_lab_pt1, poof