Dominando Templates de Classe em C++: Um Guia Prático
Dominando Templates de Classe em C++: Um Guia Prático
Aprenda como aproveitar templates de classe em C++ para escrever código flexível e agnóstico de tipo com exemplos claros e reais.
Templates são uma pedra angular da programação genérica em C++. Eles permitem criar componentes reutilizáveis que funcionam com qualquer tipo de dado, melhorando a clareza do código e reduzindo duplicação. C++ oferece dois tipos de templates: function templates e class templates.
- Function Templates
- Class Templates
Templates de classe permitem definir uma única classe que se adapta a múltiplos tipos de dados. Isso não apenas encurta seu código, mas também o torna mais fácil de manter.
Declarando um Template de Classe
Um template de classe começa com a palavra-chave template, seguida por uma lista de parâmetros de template entre colchetes angulares. Depois vem a definição real da classe.
template <class T> class MyClass { private: T var; public: T getVar() const; };
Aqui, T é um placeholder para o tipo de dado que será fornecido quando o template for instanciado. A palavra-chave class pode ser substituída por typename sem alterar a semântica.
Instanciando um Template de Classe
Uma vez definido um template, você pode criar objetos especificando o tipo desejado:
MyClass<int> intObj; MyClass<float> floatObj; MyClass<std::string> stringObj;
Cada instânciação gera uma classe concreta adaptada ao tipo especificado durante a compilação.
Exemplo 1: Wrapper Genérico de Número
#include <iostream> using namespace std; // Template de classe que armazena um único valor de qualquer tipo template <class T> class Number { private: T value; public: Number(T v) : value(v) {} T getValue() const { return value; } }; int main() { Number<int> intNum(7); Number<double> doubleNum(7.7); cout << "int Number = " << intNum.getValue() << endl; cout << "double Number = " << doubleNum.getValue() << endl; return 0; }
Saída
int Number = 7 double Number = 7.7
Observe que o parâmetro de template T é usado para a variável membro, argumento do construtor e tipo de retorno, permitindo que a classe funcione com qualquer tipo.
Definindo Membros Fora da Classe
Quando uma função membro é grande ou compartilhada entre especializações, você pode defini-la fora do corpo da classe:
template <class T> class Sample { public: T identity(); }; // Definição fora template <class T> T Sample<T>::identity() { return static_cast<T>(1); }
Note a repetição da declaração template<class T> antes da definição fora da classe.
Exemplo 2: Calculadora Usando Templates de Classe
#include <iostream> using namespace std; template <class T> class Calculator { private: T a, b; public: Calculator(T x, T y) : a(x), b(y) {} T add() const { return a + b; } T subtract() const { return a - b; } T multiply() const { return a * b; } T divide() const { return a / b; } void display() const { cout << "a: " << a << ", b: " << b << endl; cout << "a + b = " << add() << endl; cout << "a - b = " << subtract() << endl; cout << "a * b = " << multiply() << endl; cout << "a / b = " << divide() << endl; } }; int main() { Calculator<int> intCalc(2, 1); Calculator<float> floatCalc(2.4f, 1.2f); cout << "Resultados Int:\n"; intCalc.display(); cout << "\nResultados Float:\n"; floatCalc.display(); return 0; }
Saída
Resultados Int: a: 2, b: 1 a + b = 3 a - b = 1 a * b = 2 a / b = 2 Resultados Float: a: 2.4, b: 1.2 a + b = 3.6 a - b = 1.2 a * b = 2.88 a / b = 2
Templates com Múltiplos Parâmetros
Templates de classe podem aceitar mais de um parâmetro, e você pode até fornecer tipos padrão:
template <class T, class U, class V = int> class MultiParam { T first; U second; V third; };
Exemplo 3: Template Multi-Parâmetro
#include <iostream> using namespace std; template <class T, class U, class V = char> class ClassTemplate { private: T var1; U var2; V var3; public: ClassTemplate(T v1, U v2, V v3) : var1(v1), var2(v2), var3(v3) {} void print() const { cout << "var1 = " << var1 << endl; cout << "var2 = " << var2 << endl; cout << "var3 = " << var3 << endl; } }; int main() { ClassTemplate<int, double> obj1(7, 7.7, 'c'); cout << "valores obj1:\n"; obj1.print(); ClassTemplate<double, char, bool> obj2(8.8, 'a', false); cout << "\nvalores obj2:\n"; obj2.print(); return 0; }
Saída
valores obj1: var1 = 7 var2 = 7.7 var3 = c valores obj2: var1 = 8.8 var2 = a var3 = 0
Neste exemplo, o terceiro parâmetro de template padrão é char, mas pode ser sobrescrito como mostrado com bool em obj2.
Linguagem C
- Palavra-chave Static em C#: Dominando Variáveis, Métodos e Classes Estáticas
- Entendendo Classes Aninhadas em C#: Definição, Uso e Herança
- Dominando Operadores em C++: Guia Completo com Exemplos Práticos
- Comentários em C++: Boas Práticas para Código Legível e Manutenível
- Entendendo Classes de Armazenamento em C++: Escopo, Tempo de Vida e Uso
- Entendendo Polimorfismo em C++: Guia Prático
- Dominando Abstração de Dados em C++: Simplifique Design com Separação Interface-Implementação
- Encapsulamento de Dados em C++: Proteja Seu Código
- Interfaces em C++: Dominando Classes Abstratas e Funções Virtuais Puras
- Dominando Templates em C++: Guia para Programação Genérica