Curso completo de linguagem C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
track17.html

index << >>

17. Classes genéricas

17.1 Visão geral A linguagem c++ oferece recursos de programação genérica, isto é, você pode criar classes, propriedades e métodos que são preparados para trabalhar com qualquer tipo de dado, podendo este tipo de dado ser os primitivos (int, float...) ou os tipos de dados definidos pelo usuário como struct e ainda mesmo os objetos das classes. É um recurso poderoso e complexo da linguagem c++ que deve ser explorado com cuidado e vagarosamente. No capítulo 5 sobre funções implementamos uma função diga() para exibir qualquer tipo de dado primitivo como argumento: // protótipo das funções genéricas template <typename tipo_geral> void diga (tipo_geral nval); //******************* implementação das funções genéricas template <typename tipo_geral> void diga (tipo_geral nval) { cout << "\t Argumento: " << nval << "\n"; } // endfunction: diga(tipo_geral) O mecanismo de funcionamento das funções genéricas é simples: se seu programa chama a função diga() com o tipo inteiro ou outro tipo, o compilador cria uma versão dessa função com esse tipo de dado, fazendo a substituição do placeholder tipo_geral pelo tipo primitivo utilizado. (*) placeholder numa tradução ruim é 'guardador de lugar' que identifica ou mantém um espaço reservado enquanto o dono principal do espaço não chega. Outro termo utilizado em inglês com sentido semelhante é dummy. Continuando, então se você chamou a função diga() com o tipo float, o compilador cria essa versão da função diga: void diga (float nval) { cout << "\t Argumento: " << nval << "\n"; } Essa recapitulação da função genérica diga() é só um aquecimento, vamos ver agora no subtópico abaixo a sintaxe de definição de classes genéricas que é um pouco diferente da definição de funções genéricas. 17.2 Definindo uma classe genérica
// cls_generica.cpp // Este programa ilustra o uso de classe genérica #include <iostream> using namespace std; // definicao da classe genérica Megafone template <typename tipo_geral> class Megafone { public: tipo_geral m_dado; Megafone (tipo_geral dado); void diga(int nvezes = 1); }; // fim da classe // definição do construtor template <typename tipo_geral> Megafone<tipo_geral>::Megafone(tipo_geral dado): m_dado(dado) {} // definição do método diga template <typename tipo_geral> void Megafone<tipo_geral>::diga (int nvezes) { if (nvezes > 1) for (int ncx=0; ncx < nvezes; ncx++) cout << m_dado; else cout << m_dado << "\n"; cout << "\n"; } // fim do método diga() // protótipo das nossas funções básicas void inicio(); void fim(); // --------------- Nossa função principal começa aqui... int main() { inicio(); // Instanciamento de um objeto de classe genérica Megafone<string> linha("-"); Megafone<string> aviso("\tPress start to play"); Megafone<int> credito(2); // uso normal dos métodos linha.diga(40); aviso.diga(); cout << "\tCredits: "; credito.diga(); linha.diga(40); fim(); } // endmain // -------------------------- funções ---------------------------------------- void inicio() { system("title cls_generica.cpp"); system("color f0"); cout << "\n"; } // endfunction: inicio() void fim() { cout << endl; system("pause"); } // endfunction: fim()
Definição da classe genérica // definicao da classe generica Megafone template <typename tipo_geral> class Megafone { public: tipo_geral m_dado; Megafone (tipo_geral dado); void diga(int nvezes = 1); }; // fim da classe Tal como nas funções genéricas você deve definir um nome para o tipo genérico. Aqui chamamos nosso tipo genérico de tipo_geral: template <typename tipo_geral> Definição dos métodos // definicao do construtor template <typename tipo_geral> Megafone<tipo_geral>::Megafone(tipo_geral dado): m_dado(dado) {} // definicao do metodo diga template <typename tipo_geral> void Megafone<tipo_geral>::diga (int nvezes) { if (nvezes > 1) for (int ncx=0; ncx < nvezes; ncx++) cout << m_dado; else cout << m_dado << "\n"; cout << "\n"; } // fim do metodo diga() Na implementação dos métodos de classe genérica eles devem ser precedidos pela sintaxe de declaração do tipo genérico:template <typename tipo_geral> E após o nome da classe você deve colocar o nome do tipo geral dessa forma: tipo_de_retorno Nome_da_classe<tipo_geral>::Método() { // código } Instanciando os objetos // Instanciamento de um objeto de classe generica Megafone<string>; linha("-"); Megafone<string> aviso("\tPress start to play"); Megafone<int> credito(2); // uso normal dos metodos linha.diga(40); aviso.diga(); cout << "\tCredits: "; credito.diga(); linha.diga(40); Veja que após o nome da classe você deve colocar o tipo de dado entre os bicos. Note que nosso método diga() é capaz de mostrar um objeto da classe string; isso somente é possível porque a classe string sobrecarrega o operador << ( operador<<() ) que retorna uma c-string ao objeto cout.
index << >>


Produzido por Gameprog: Jair Pereira - Fev/2006 - Junho/2013 © gameprog.br@gmail.com http://www.gameprog.com.br