Crie um template de classe que representa um vetor de qualquer tipo. O tamanho desse vetor deve ser definido dinamicamente no momento da criação do objeto. Efetue a sobrecarga do operador colchetes para que a gente possa acessar facilmente um elemento do vetor.
Passo 1
Vamos nessa, pessoal.
Nesse exercício envolve um monte de conhecimentos: templates, alocação dinâmica e sobrecarga de operador. É bastante coisa! Mas vai ser divertido fazer essa questão.
A questão pede pra criar um template de classe que represente um vetor, então vamos chamar essa template de .
Dentro do template vamos ter que usar um array alocado dinamicamente para armazenar os elementos do nosso vetor. Se você se lembrar, a melhor forma de fazer isso é alocando a array dentro do construtor, e liberando a memória dentro do destruidor. Depois vamos sobrecarregar o operador .
Então vamos começar com o cabeçalho da questão:
Passo 2
Então vamos declarar o template de classe , e dentro do template vamos declarar o protótipo de todos os métodos.
Para criar um template de classe a gente utiliza a palavra-chave e determinamos um tipo genérico usando e em seguida declaramos a classe:
Template iniciado. Agora vamos pro encapsulamento privado, e declaramos o atributo ponteiro usando o tipo genérico . Afinal de contas, é esse ponteiro que vamos usar para alocar a memória dinamicamente, então ele precisa apontar para o tipo que vamos utilizar no nosso template.
O tamanho do sempre será um valor inteiro, então criamos um atributo que vai armazenar a quantidade de elementos do .
Agora vamos para o encapsulamento público. Aqui vamos criar o protótipo de todos os nossos métodos
Primeiro declararmos o construtor, que é um método sem tipo, e que vai receber o valor inteiro de . Ou seja, é só declarar um construtor normalmente.
Depois declaramos o destruidor, que também é um método sem tipo, então é só declarar um destruidor normalmente.
Agora vamos pensar na sobrecarga do operador . O primeiro detalhe é que esse operador só pode ser sobrecarregado como função-membro da classe.
O símbolo do operador é , e o parâmetro que vamos receber é o índice a ser acessado. O segundo detalhe é que o tipo da função será !
O tipo é pois o operador vai retornar um elemento do e o tipo dos elementos do são determinados de acordo com o tipo genérico do template. O símbolo está aí, pois queremos retornar uma referência para o valor do , isso torna possível que o valor seja alterado se necessário.
Pronto. O protótipo do template está desenvolvido. O próximo passo é desenvolver o conteúdo dos métodos.
Passo 3
O primeiro método que vamos desenvolver é o construtor.
Aqui temos que notar uma pequena diferença. Quando queremos desenvolver um método que foi declarando dentro de um template, nós temos que adicionar o prefixo de template, e antes do operador temos que adicionar os tipos genéricos entre chaves.
Ou seja, um método de template tem que ser escrito que nem um template de função, mas adicionando o nome da classe com o operador , da seguinte forma:
O construtor é um método sem tipo de retorno e com o mesmo nome da classe, então fica assim:
Dentro do construtor, a primeira coisa a ser feita é inicializar o parâmetro
Em seguida, alocamos no ponteiro um array dinâmico com a dimensão :
Prontinho! O array dinâmico foi criado com sucesso. Agora, vamos usar um loop para pedir pro usuário preencher cada uma das posições do array:
Passo 4
Agora vamos desenvolver o destruidor. Novamente precisamos lembrar que um método de template tem que ser escrito que nem uma função template, mas adicionando o nome da classe e o operador , da seguinte forma:
Dentro do destruidor temos que liberar a memória que foi alocada dinamicamente. Para isso vamos usar o operador para apagar o conteúdo do endereço de memória apontado por .
E é só isso. O destruidor está prontinho!
Passo 5
Agora vamos dar uma olhada detalhada na sobrecarga do operador . Novamente, quando escrevemos um um método de template precisamos adicionar os prefixos de template:
No caso da sobrecarga do operador o tipo de retorno é .
A principal função desse operador é mostrar o conteúdo existente um uma posição do array. Dentro do colchete a gente escreve um índice, e o operador sobrecarregado retorna a posição correspondente do array.
E é só isso! Usando o no retorno da sobrecarga a gente possibilita mais usos do operador .
Com isso a classe está concluída, e só falta a gente testar.
Passo 6
Agora só falta a gente testar pra garantir que tudo funciona!
Vamos criar um objeto do tipo e vamos inicia-lo com tamanho . Assim que o objeto for criado o construtor vai entrar em ação, e vai pedir que a gente preencha o vetor. Para fins de testes, vou imprimir o conteúdo da posição .
Em seguida vamos criar um outro objeto da classe , mas dessa vez usando o tipo . E vamos imprimir a primeira posição desse objeto.
E pronto, vamos rodar o programa:
E o programa rodou tranquilamente. Como estamos usando templates, foi super tranquilo alterar o tipo de dados usado no Vetor!
E veja só a última mensagem: é o destruidor entrando em ação e limpando a memória.
E por hoje é isso! Até a próxima!