Aprenda C++

  • Página Inicial
  • Contato!
  • Tudo sobre C++ Parte 1!
  • Tudo sobre C++ Parte 2!
  • Tudo sobre C++ Parte 3!
  • Tudo sobre C++ Parte 4!
  • Tudo sobre C++ Parte 5!
  • Tudo sobre C++ Parte 6!
  • Tudo sobre C++ Parte 7!
  • Tudo sobre C++ Parte 8!
  • Tudo sobre C++ Parte 9!
  • Tudo sobre C++ Parte 10!
  • Tudo sobre C++ Parte 11!
  • Tudo sobre C++ Parte 12!
  • Tudo sobre C++ Parte 13!
  • Tudo sobre C++ Parte 14!
  • Tudo sobre C++ Parte 15!
  • Tudo sobre C++ Parte 16!
  • Orientação a Objetos em C++ - Parte 3

    Classes, Get e Set

    Crie um novo projeto e nele, um novo arquivo de cabeçalho com o nome classes.h.

    Note que nesse caso, teremos alguns atributos privados, que só podem ser manipulados pela própria classe (encapsulamento), para isso teremos que criar métodos getters e setters para podermos usar eles.

    
    #ifndef CLASSES_H_INCLUDED
    #define CLASSES_H_INCLUDED
    #include <iostream>
    
    class Veiculo {
        public:
            int velocidade;
            int tipo;
            Veiculo(int tp); // Construtor
        private:
            std::string nome;
            int velMax;
            bool ligado;
    };
    
    Veiculo::Veiculo(int tp) {
        if(tp == 1) {
            this->velMax = 200;
            this->nome = "Carro";
        }
        else if(tp == 2) {
            this->velMax = 250;
            this->nome = "Moto";
        }
        else if(tp == 3) {
            this->velMax = 150;
            this->nome = "Caminhão";
        }
    }
    
    #endif // CLASSES_H_INCLUDED
    
    
    

    E pra tentar executar na principal:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Veiculo(1);
        
        v1->velMax = 250; // Não é possível alterar por ser privado.
    
        cout << v1->velMax; // Não é possível executar por ser privado.
    
        delete v1;
    
        return 0;
    }
    
    

    Como visto, esse código acima dará erro por tentarmos manipular atributos privados. Para isso, criamos um método getter e setter. Adicione isso no Classes.h:

    
    const int Veiculo::getVelMax() {
        return velMax;
    }
    void Veiculo::setVelMax(int vm) {
        velMax = vm;
    }
    
    

    PS: Não esqueça de colocar na classe a declaração dos métodos em público, assim:

    
    const int getVelMax();
    void setVelMax(int vm);
    
    

    E agora poderemos executar normalmente assim:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Veiculo(1);
    
        v1->setVelMax(250);
    
        cout << v1->getVelMax();
    
        delete v1;
    
        return 0;
    }
    
    

    Agora podem ver que funciona normalmente. Isso torna o código mais seguro, já que o atributo é privado, mas pode ser alterado pelo método por ser público e este alterar dentro da classe.

    PS: O const não é obrigatório no getter, mas garante mais segurança, sempre coloque em todos os getters manipulados. O const em POO é para métodos que não alterarão nenhum atributo, pode ser usado em qualquer método, mas de preferência é usado em métodos getters.

    Veja outro exemplo, com mais objetos:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Veiculo(1);
        Veiculo *v2 = new Veiculo(2);
        Veiculo *v3 = new Veiculo(3);
    
        cout << v1->getVelMax() << endl;
        cout << v2->getVelMax() << endl;
        cout << v3->getVelMax() << endl;
    
        delete v1;
        delete v2;
        delete v3;
    
        return 0;
    }
    
    

    Caso não queira que podemos alterar pelo método setter também, coloque ele como privado na classe.

    Crie também os métodos setter e getters ligado públicos, para alterar o atributo ligado, assim:

    
    const bool Veiculo::getLigado() {
        return ligado;
    }
    void Veiculo::setLigado(int l) {
        if(l == 1) {
            ligado = true;
        }
        else if(l == 0) {
            ligado = false;
        }
    }
    
    

    Dentro da classe:

    
    const bool getLigado();
    void setLigado(int l);
    
    

    Crie também um método para visualizarmos o estado dos carros:

    
    void Veiculo::estado() {
        if(this->getLigado()) {
            std::cout << "Veículo " << nome << " está ligado!" << std::endl;
        }
        else {
            std::cout << "Veículo " << nome << " está desligado!" << std::endl;
        }
    }
    
    

    E no arquivo principal podemos fazer isso:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Veiculo(1);
        Veiculo *v2 = new Veiculo(2);
        Veiculo *v3 = new Veiculo(3);
    
        v1->setLigado(1);
        v2->setLigado(0);
        v3->setLigado(1);
    
        cout << v1->getVelMax() << endl;
        cout << v2->getVelMax() << endl;
        cout << v3->getVelMax() << endl;
    
        v1->estado();
        v2->estado();
        v3->estado();
    
        delete v1;
        delete v2;
        delete v3;
        
        return 0;
    }
    
    

    PS: O public permite acesso em qualquer parte do programa, o private só permite acesso na classe da qual ela pertence, e ainda existe o protected, que só permite acesso na classe e nas filhas dela (é um meio-termo entre public e private).

    Classes e Herança

    Com a herança, uma classe pode herdar propriedades de outras classes, podendo ter outras adicionadas.

    Vamos criar um novo projeto e um file com as classes. Esse é o código da classe:

    
    class Veiculo {
        public:
            int vel;
            int blind;
            int rodas;
        private:
            int tipo;
            int velMax;
            bool arma;
    };
    
    

    No caso acima, a classe Veiculo (classe pai) é genérica, e classes como Moto e Carro (filhas) herdam características da mesma.

    Vamos criar a classe Moto, assim:

    
    class Moto : public Veiculo {
        
    };
    
    

    No caso acima, ele já está herdando as coisas de Veiculo, mas sem adicionar mais nada, isso é a herança pobre.

    No arquivo principal, crie o objeto assim:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Moto *v1 = new Moto();
    
        delete v1;
    
        return 0;
    }
    
    

    Ou assim, de forma que usaremos apenas o que for descrito na classe pai, ganhando em polimorfismo:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Moto();
    
        delete v1;
    
        return 0;
    }
    
    

    Agora, crie o construtor na classe Moto, inicializando os atributos públicos assim:

    
    class Moto : public Veiculo {
        public:
            Moto(); // Construtor
    };
    
    Moto::Moto() {
        vel = 0;
        blind = 0;
        rodas = 2;    
    }
    
    

    E no arquivo principal:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Moto();
        
        cout << v1->rodas << endl;
    
        delete v1;
    
        return 0;
    }
    
    

    Para alterarmos os atributos privados, faremos métodos setters na classe Veiculo, e também um método para exibição, de forma que ficará assim:

    
    class Veiculo {
        public:
            int vel;
            int blind;
            int rodas;
            // Setters
            void setTipo(int tp);
            void setVelMax(int vm);
            void setArma(bool ar);
            void imp();
        private:
            int tipo;
            int velMax;
            bool arma;
    };
    
    void Veiculo::imp() {
        std::cout << "Tipo de veículo: " << tipo << std::endl;
        std::cout << "Velocidade máxima: " << velMax << std::endl;
        std::cout << "Quantidade de rodas: " << rodas << std::endl;
        std::cout << "Blindagem: " << blind << std::endl;
        std::cout << "Armamento: " << arma << std::endl;
        std::cout << "------------------------" << std::endl;
    }
    
    void Veiculo::setTipo(int tp) {
        tipo = tp;
    }
    void Veiculo::setVelMax(int vm) {
        velMax = vm;
    }
    void Veiculo::setArma(bool ar) {
        arma = ar;
    }
    
    

    E no construtor da Moto, basta colocar a chamada dos métodos setters:

    
    class Moto : public Veiculo {
        public:
            Moto(); // Construtor
    };
    
    Moto::Moto() {
        vel = 0;
        blind = 0;
        rodas = 2;
        setTipo(1);
        setVelMax(120);
        setArma(false);
    }
    
    

    No método principal, podemos fazer assim:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Moto();
    
        v1->imp();
    
        delete v1;
    
        return 0;
    }
    
    

    Crie agora, outra classe que herdará de veículo, a classe Carro, assim:

    
    class Carro : public Veiculo {
        public:
            Carro(); // Construtor
    };
    
    Carro::Carro() {
        vel = 0;
        blind = 0;
        rodas = 4;
        setTipo(2);
        setVelMax(200);
        setArma(false);
    }
    
    

    E também a classe Tanque, da mesma forma:

    
    class Tanque : public Veiculo {
        public:
            Tanque(); // Construtor
    };
    
    Tanque::Tanque() {
        vel = 0;
        blind = 1;
        rodas = 8;
        setTipo(3);
        setVelMax(160);
        setArma(true);
    }
    
    

    E no método principal:

    
    #include <iostream>
    #include "Classes.h"
    
    using namespace std;
    
    int main() {
        Veiculo *v1 = new Moto();
        Veiculo *v2 = new Carro();
        Veiculo *v3 = new Tanque();
    
        v1->imp();
        v2->imp();
        v3->imp();
    
        delete v1;
        delete v2;
        delete v3;
    
        return 0;
    }
    
    

    Em C++ também podemos fazer heranças múltiplas, que é quando uma classe herda de mais de uma classe ao mesmo tempo, faríamos algo assim:

    
    class Herdeira : public Classe1, public Classe2 {
    
    };
    
    

    E nas classes filhas de outras, também podemos fazer o "super", que é a herança de construtores de classes pais, dessa forma:

    
    Classe2::Classe2(int n1, int n2, int n3) : Classe1(n1, n2) { // Indica a classe pai, no segundo parenteses são só os parâmetros do construtor da classe pai sem declaração de tipo.
        this->num3 = n3;
    }
    
    

    Caso tenha herança múltipla, os construtores de ambas as classes pais deverão ser indicadas após os dois pontos, separadas por vírgulas.