Introdução aos Modelos (Templates)
No C++, os modelos são uma poderosa ferramenta de reutilização de código, permitindo que funções e classes operem com diferentes tipos sem a necessidade de repetir o código. A sintaxe básica para definir um modelo é:
template <typename T>
O tipo T atua como um parâmetro genérico, substituível por qualquer tipo real durante a instância.
Modelos de Funções
Os modelos de função premitem criar funções que funcionam com múltiplos tipos. Sua sintaxe geral é:
template <typename T1, typename T2, ..., typename Tn>
TipoRetorno NomeDaFuncao(Parâmetros) { /* corpo */ }
Exemplo prático de troca de valores entre duas variáveis usando um modelo de função:
template <typename Tipo>
void Trocar(Tipo& a, Tipo& b) {
Tipo temp = a;
a = b;
b = temp;
}
int main() {
double valor1 = 3.14, valor2 = 2.71;
Trocar<double>(valor1, valor2); // Instanciação explícita
return 0;
}
Modelos de Classes
Classes modelo permitem definir estruturas que operam com tipos genéricos. A declaração começa com o cabeçalho do modelo, seguido da definição da classe:
template <typename T1, typename T2>
class NomeDaClasse { /* membros */ };
Exemplo: uma classe Ponto que armazena coordenadas com tipos distintos:
#include <iostream>
#include <string>
using namespace std;
template <typename X, typename Y>
class Ponto {
public:
Ponto(X coordenadaX, Y coordenadaY) : x(coordenadaX), y(coordenadaY) { }
X obterX() const;
void atribuirX(X novoX);
Y obterY() const;
void atribuirY(Y novoY);
private:
X x;
Y y;
};
// Definição dos métodos fora da classe
template <typename X, typename Y>
X Ponto<X, Y>::obterX() const {
return x;
}
template <typename X, typename Y>
void Ponto<X, Y>::atribuirX(X novoX) {
x = novoX;
}
template <typename X, typename Y>
Y Ponto<X, Y>::obterY() const {
return y;
}
template <typename X, typename Y>
void Ponto<X, Y>::atribuirY(Y novoY) {
y = novoY;
}
int main() {
Ponto<int, int> ponto1(5, 10);
cout << "x=" << ponto1.obterX() << ", y=" << ponto1.obterY() << endl;
Ponto<float, double> ponto2(3.14f, 9.81);
cout << "x=" << ponto2.obterX() << ", y=" << ponto2.obterY() << endl;
Ponto<string, int> ponto3("Coordenada", 42);
cout << "x=" << ponto3.obterX() << ", y=" << ponto3.obterY() << endl;
// Uso com ponteiro
Ponto<string, float>* p = new Ponto<string, float>("Teste", 1.5);
cout << "x=" << p->obterX() << ", y=" << p->obterY() << endl;
delete p;
return 0;
}