Neste tutorial de nosso curso de C++, vamos esclarecer um pouco mais sobre as variáveis dos objetos bem como aprender o que são membros estáticos e como usá-los na prática.
Membros de instâncias (objetos)
Recordando um pouco nosso estudo das funções, vimos lá que, comumente, as variáveis declaradas dentro de uma função, são ditas locais e temporárias. Pois só existem dentro da função e são deletadas da memória quando a função termina. Nas classes, ocorre algo parecido.Quando temos uma classe 'Car' e o atributo 'engine', e fazemos:
BMW.engine = 4;
fusca.engine = 1;
Embora o nome da variável seja a mesma, cada objeto tem sua própria variável, onde uma não altera a outra. Ou seja, são criadas 'cópias' dessas variáveis.
Assim, as variáveis são próprias de cada instância, mesmo tendo o mesmo nome e os objetos se originando da mesma Classe.
Membros estáticos de uma Classe
Porém, as vezes não queremos que cada instância tenho seu próprio atributo, pode ser necessário ter um atributo que é exatamente o mesmo (mesmo local de memória), para todos os objetos.
E é possível fazer isso, tanto para variáveis como para funções.
Por exemplo, vamos supor que você é o programador que vai cuidar do sistema de uma grande empresa, e cada vez que uma pessoa é contratada, um objeto do tipo Funcionario deve ser criado. E cada vez que um funcionário é demitido, um objeto é excluído. Como manter o controle de quantos funcionários existem?
Simples, só criar uma variável estática, que é incrementada toda vez que um objeto for instanciado e é decrementada toda vez que um objeto for excluído.
Variável estática
Para criar uma variável estática, basta usar a palavra-chave static antes de declarar a variável.
Vamos criar a classe "Car.h":
#ifndef CAR_H #define CAR_H class Car { public: Car(); ~Car(); int getTotal(); private: static int total; }; #endif // CAR_H
Veja que declaramos a variável inteira 'total' como estática. Vamos ver a implementação, o 'Car.cpp':
#include "Car.h" int Car::total = 0; Car::Car() { total++; } Car::~Car() { total--; } int Car::getTotal() { return total; }
A primeira coisa que fizemos foi inicializar a variável total com 0, afinal, inicialmente, nenhum objeto foi instanciado. A função construtora simplesmente incrementa o valor de total, ou seja, cada vez que instanciarmos um objeto, essa variável vai ser incrementada.
E na função destrutora, decrementamos esse variável.
E como ela é estática, esse valor vai representar o número de objetos criados a partir da classe Car. Veja como ficou nossa main.cpp:
#include <iostream> #include "Car.h" using namespace std; int main() { Car *ptr1, *ptr2, *ptr3; ptr1 = new Car(); ptr2 = new Car(); ptr3 = new Car(); cout<<"Numero de objetos instanciados: "<< (*ptr1).getTotal() <<endl; delete ptr3; cout<<"Numero de objetos instanciados: "<< (*ptr1).getTotal() <<endl; return 0; }
Primeiro, criamos três ponteiros do tipo Car. Em seguida, fazemos a alocação dinâmica de memória.
Printamos o resultado após essas 3 alocações. Deletamos o terceiro ponteiro (isso faz com que a função destructor ~Car() seja acionada), então printamos novamente o número de instâncias.
E o resultado é:
"Numero de objetos instanciados: 3"
"Numero de objetos instanciados: 2"
Note que usamos a função do primeiro objeto, '*ptr1', que criamos, isso prova que a variável 'total' é a mesma, para todos os objetos.
Função estática
Assim como existem as variáveis estáticas, também podemos criar funções estáticas, para uma classe. Porém, elas tem uma característica bem específicas: só podem atuar sobre variáveis estáticas.
Vamos criar a função zero(), que vai zerar a variável 'total'. Nossa classe "Car.h":
#ifndef CAR_H #define CAR_H class Car { public: Car(); ~Car(); int getTotal(); static void zero(); private: static int total; }; #endif // CAR_H
Nossa implementação "Car.cpp"
#include "Car.h" int Car::total=0; Car::Car() { total++; } Car::~Car() { total--; } int Car::getTotal() { return total; } void Car::zero() { total=0; }
Por fim, nossa main:
#include <iostream> #include "Car.h" using namespace std; int main() { Car *ptr1, *ptr2, *ptr3; ptr1 = new Car(); ptr2 = new Car(); ptr3 = new Car(); cout<<"Numero de objetos instanciados: "<< (*ptr1).getTotal() <<endl; delete ptr3; cout<<"Numero de objetos instanciados: "<< (*ptr1).getTotal() <<endl; Car::zero(); cout<<"Numero de objetos instanciados: "<< (*ptr1).getTotal() <<endl; return 0; }
E o resultado é:
"Numero de objetos instanciados: 3"
"Numero de objetos instanciados: 2"
"Numero de objetos instanciados: 0"
Uma coisa interessante sobre membros estáticos, é que eles existem antes mesmo de qualquer instância da classe ser criada. Assim, sem criar objetos nenhum, você já pode acessar 'total' e 'zero()'.
Por exemplo, você pode pedir um valor ao usuário e usar esse valor para alterar uma variável estática de uma classe, antes mesmo de começar a instanciar objetos dela, e começar a trabalhar com os objetos a partir de um valor previamente determinado pelo usuário.
Nenhum comentário:
Postar um comentário