Construtores
Agora que já sabemos o que são métodos de uma classe podemos conhecer alguns métodos especiais como os construtores. Como o próprio nome diz eles servem para "construir" a classe e se diferenciam de outros por ter o mesmo nome da classe que eles constroem. Vejamos um exemplo:
- #include <iostream>
- #include <string>
- using namespace std;
- int main() {
- class Aluno {
- public:
- string nome;
- int nota;
- Aluno(string x, int y){
- nome =x;
- nota =y;
- }
- };
- Aluno aluno1("Gabriel",10);
- Aluno aluno2("Marta",8);
- Aluno aluno3("Joaquim",9);
- cout <<aluno1.nome << " " << aluno1.nota << "\n";
- cout <<aluno2.nome << " " << aluno2.nota <<"\n";
- cout <<aluno3.nome << " " << aluno3.nota <<"\n";
- return 0;
- }
Nesse exemplo estamos definindo que a classe Aluno terá dois atributos: nome e nota, mas diferente dos exemplos anteriores eu tenho da linha 10 a 13 a definição de um método com o mesmo nome da classe que recebe dois parâmetros, x e y, como os mesmos tipos dos atributos.
Como o método tem o mesmo nome da classe, ele é um método construtor e repare que nas linhas 11 e 12 eu estou determinando que aos atributos da classe sejam atribuídos os valores dos parâmetros passados para o método.
Agora repare nas linhas 15, 16 e 17 que eu instanciei os objetos aluno1, aluno2 e aluno3, usando a classe Aluno e já iniciando seus valores como parâmetros do métodos construtor. Veja como ficou mais fácil a atribuição de valores assim. Eu usei muito menos linhas para isso.
Setters e Getters
Em uma aula anterior eu falei a respeito dos especificadores de acesso, lembra? Falei que eles poderiam ser public, private e protected. No entanto não dei exemplos de uso do private, mas agora vamos falar deles.
Você pode facilmente acessar por instruções de fora da classe os atributos de uma classe com especificador de acesso public, porque ele, como o nome diz, são públicos. No entanto é uma boa prática limitar o acesso à algumas informações sensíveis definindo o atributo como private (privado) e chamamos essa proteção de encapsulamento.
Quando eu determino na classe que um atributo terá especificador de acesso private, eu só vou conseguir acessar esse atributo com o auxílio de algum método público dentro dela. É ai que entram os Setters e o Getters que são métodos públicos dentro de uma classe para permitir que instruções de fora alcancem esses atributos privados.
Setter vem da palavra Set, que significa definir ou ajustar, assim o Setter é o método que permite atribuir um valor ao atributo private. Enquanto Getter, que vem de Get, que significa pegar, é o método que permite ler e adquirir o valor desse atributo. Vejamos um exemplo:
- #include <iostream>
- #include <string>
- using namespace std;
- int main() {
- class Aluno {
- public:
- string nome;
- int nota;
- Aluno(string x, int y){
- nome =x;
- nota =y;
- }
- void SetFone(string z){
- fone=z;
- }
- string GetFone(){
- return fone;
- }
- private:
- string fone;
- };
- Aluno aluno1("Gabriel",10);
- aluno1.SetFone("11967347088");
- cout <<"Nome: " << aluno1.nome << "\n";
- cout <<"Nota: " << aluno1.nota <<"\n";
- cout <<"Fone: " << aluno1.GetFone() <<"\n";
- return 0;
- }
Nesse exemplo eu continuo usando a classe Aluno com seu construtor, mas agora eu inclui na linha 21 um especificador de acesso private para o atributo fone, de forma que eu só consigo acessá-lo com o uso de métodos públicos dentro da classe.
Assim eu criei da linha 15 a 17 o Setfone() que me permite atribuir um valor a esse atributo privado, como estou na fazendo na linha 25. Também criei nas linhas 18 a 20 o GetFone() que me retorna o valor que está no atributo privado fone.
Usando o This
O significado da palavra this geralmente é "esse" ou "este". Aqui em C++ ele será utilizado dentro de um Setter para servir de ponteiro na atribuição de um objeto que está sendo referenciado. Seria como se eu usasse a frase "esse objeto fulano será igual a tal coisa". Vejamos um exemplo:
- #include <iostream>
- #include <string>
- using namespace std;
- int main() {
- class Aluno {
- private:
- string nome;
- int nota;
- public:
- Aluno(string x, int y){
- SetNome(x);
- SetNota(y);
- }
- void SetNome(string x){
- this->nome=x;
- }
- void SetNota(int y){
- this->nota=y;
- }
- string GetNome(){
- return nome;
- }
- int GetNota(){
- return nota;
- }
- };
- Aluno aluno1("Gabriel",10);
- cout <<"Nome: " << aluno1.GetNome() << "\n";
- cout <<"Nota: " << aluno1.GetNota() <<"\n";
- return 0;
- }
Nesse exemplo o método construtor da linha 11 a 14 está utilizando um setter para definir o atributo nome e outro setter para definir o atributo nota. Já das linhas 15 a 20 eu tenho a definição desses dois setter que passam a utilizar o this para apontar para o endereço de memória do objeto.
Com isso vimos mais um dos quatro pilares da POO que é o encapsulamento e já estamos prontos para avançar mais um pouco pra falar de polimorfismo na próxima aula.
Referências
DEITEL, H. M. DEITEL, P. J. C++: Como programar. Pearson Education do Brasil. 2006.
GBDONLINE. Learn C++ Programming. Disponível em: <https://learn.onlinegdb.com/c%2B%2B_for_beginners> Acesso em 05 ago. 2024.
W3SCHOOLS. C++ Tutorial. Disponível em: <https://www.w3schools.com/cpp/default.asp> Acesso em 05 ago. 2024.