Classes: Construtores e Destrutores
Esta aula abordará sobre dois métodos especiais: O método Construtor e o método Destrutor.
CONSTRUTORES
Observe o Programa 1 que é o mesmo programa utilizado para exemplificar as funções de acesso e as funções modificadoras na aula passada.
#include <iostream> #include <cmath> using namespace std; class filtroRC { private:
float f_corte; //polo do filtro.... float R;
float C; public:
void zera(void); //logo logo veremos construtores... void setR(float aux);
void setC(float aux); float getF_Corte(void); }; void filtroRC::zera(void) { R = C = f_corte = 0; }
void filtroRC::setR(float aux) {
R = aux;
if ( R && C ) f_corte = 1/(R*C); //se R e C diferente de 0 calcula f }
void filtroRC::setC(float aux) {
C = aux;
if ( R && C ) f_corte = 1/(R*C); //se R e C diferente de 0 calcula f }
float filtroRC::getF_Corte(void) {
return f_corte/(2*M_PI); //retorna frequência de corte em Hz... } int main() { filtroRC f1; float a; f1.zera();
cout << "Digite a Resistencia do filtro: "; cin >> a; f1.setR(a);
cout << "Digite a Capacitancia do filtro: "; cin >> a; f1.setC(a);
cout << "A frequencia de corte do filtro e': " << f1.getF_Corte() << "Hz\n"; system("PAUSE");
return 0; }
Note que existe uma função que zera todos os atributos da classe (void filtroRC::zera(void)).
Esta função só foi implementada para inicializar o objeto, de modo que as funções modificadoras evitassem calcular a frequência de corte antes que os valores de R e C fossem devidamente configurados. Um Construtor realiza exatamente esta tarefa, porém o construtor é chamado logo que o objeto é criado, e não necessita ser diretamente chamado. Examine o Programa 2, onde o Programa 1 é modificado de modo a incluir um Construtor na classe.
#include <iostream> #include <cmath> using namespace std; class filtroRC { private: float f_corte; float R; float C; public:
void setR(float aux); void setC(float aux); float getF_Corte(void);
filtroRC(void); //CONSTRUTOR: OBSERVE COM ATENÇÃO... NÃO EXISTE TIPO!
};
void filtroRC::setR(float aux) {
R = aux;
if ( R && C ) f_corte = 1/(R*C); //se R e C diferente de 0 calcula f
}
void filtroRC::setC(float aux) {
C = aux;
if ( R && C ) f_corte = 1/(R*C); //se R e C diferente de 0 calcula f
}
float filtroRC::getF_Corte(void) {
return f_corte/(2*M_PI); //retorna frequência de corte em Hz...
}
filtroRC::filtroRC(void) {
cout << "Contrutor foi executado...\n"; //só para visualizar
setR(0); setC(0); f_corte = 0; //que o construtor foi chamado
}
int main() {
filtroRC f1; float a;
cout << "Digite a Resistencia do filtro: "; cin >> a; f1.setR(a);
cout << "Digite a Capacitancia do filtro: "; cin >> a; f1.setC(a);
cout << "A frequencia de corte do filtro e': " << f1.getF_Corte() << "Hz\n"; system("PAUSE");
return 0; }
Observe atentamente para a sintaxe. Ao declarar o construtor, nenhum tipo de retorno foi especificado, nem mesmo o tipo void. Note também que no construtor da classe filtroRC as próprias funções modificadoras são utilizadas para alterar os valores dos atributos.
Analise a saída do programa. O construtor é chamado logo que o objeto f1 é criado, inicializando o objeto f1 com os valores especificados pelo Construtor.
Nota: Mesmo se não houver Construtor na classe, o compilador executa um Construtor padrão, que é um construtor sem parâmetros e vazio.
O Programa 3 apresenta outro exemplo. Modifique o Construtor da classe e observe o resultado. #include <iostream> using namespace std; class hipotetica { public: int var; hipotetica(void); }; hipotetica::hipotetica(void) { var = 5; } int main() { hipotetica h1;
cout << "Valor atribuido pelo construtor: " << h1.var << endl; system("PAUSE");
return 0; }
Programa 3 Outro exemplo de Construtor.
É possível passar parâmetros para construtores, de modo a inicializar os atributos com valores especificados externamente a classe (pelo usuário) quando o objeto é criado. Estude atentamente o Programa 4.
#include <iostream> using namespace std; class hipotetica { public: int var; hipotetica(int a); }; hipotetica::hipotetica(int a) { var = a; } int main() {
hipotetica h1 = hipotetica(5); //um modo de utilizar contrutores c/ param.
hipotetica h2(2); //outro modo
cout << "Valor atribuido para h1 pelo construtor: " << h1.var << endl; cout << "Valor atribuido para h2 pelo construtor: " << h2.var << endl; system("PAUSE");
return 0; }
Programa 4 Construtores parametrizados.
Veja que, no Programa 4, são criados dois objetos (h1 e h2). Cada um dos objetos é criado utilizando-se uma forma diferente de chamar o construtor. Em ambos os casos, o valor inicialmente atribuído ao atributo var é passado como parâmetro. A escolha da forma como o objeto será inicializado fica a critério do usuário da classe.
D
ESTRUTORESAssim como um objeto é construído e inicializado utilizando-se um construtor, existe outra função-membro especial chamada Destrutor. A sintaxe utilizada para definir um Destrutor é a mesma que para o Construtor, porém precedida por um tio (~).
Diferentemente do Construtor, o Destrutor não possui uma função tão óbvia. Em programas complexos os Destrutores normalmente são encarregados de liberar memória alocada dinamicamente ou de liberar um identificador de arquivo, por exemplo. Em programas simples, no entanto, seu uso é, na maioria dos casos, supérfluo.
Quando um Destrutor não é declarado, o compilador assume um Destrutor vazio.
Estude o Programa 5 para compreender como e quando Construtores e Destrutores são chamados.
//este exemplo foi baseado em um dos exemplos do livro //C++ como programar de PJ Deitel e HM Deitel
#include <iostream> #include <string> using namespace std; class hipotetica { public: string ID; hipotetica(string aux); ~hipotetica(void); }; hipotetica::hipotetica(string aux) {
cout << "Contruindo: " << aux << endl; ID = aux;
}
hipotetica::~hipotetica(void) {
cout << "Destruindo: " << ID << endl; } hipotetica h0("Obj 00"); void funcao(void) { hipotetica h2("Obj 02"); hipotetica h3("Obj 03"); } int main() { hipotetica h1("Obj 01"); funcao(); system("PAUSE"); return 0; }
Programa 5 Construtores e Destrutores.
Exercício 1A Figura 1 apresenta o modelo de um capacitor.
Figura 1 Modelo do Capacitor.
O circuito ao lado representa o modelo equivalente de um capacitor real (na verdade é uma aproximação). No modelo, RSE é a resistência série equivalente do capacitor, que normalmente é da ordem de poucos Ohms. LSE é a indutância série equivalente. C é valor nominal da capacitância do capacitor. Trata-se de um circuito RLC série.
Crie uma classe que represente o modelo do capacitor. A classe deverá conter os atributos citados acima (todos privados), além do tipo do capacitor (eletrolítico, tântalo, cerâmico etc... utilize, para tanto, uma variável string).
A classe deverá possuir um construtor parametrizado, bem como um Destrutor padrão (vazio). Crie um método que retorne a frequência de ressonância do capacitor. Crie um método que retorne o módulo da impedância para uma frequência qualquer. Faça um programa que teste a classe. Lembre-se que ωres =1 L C⋅ e que, para o circuito em questão, Z RSE j LSE 1
C ω
ω
−
= +
. O módulo de um número complexo a + jb é:
2 2
a b
a jb