Neste artigo, você aprenderá sobre modelos em C ++. Você aprenderá a usar o poder dos modelos para programação genérica.
Os modelos são recursos poderosos do C ++ que permitem escrever programas genéricos. Em termos simples, você pode criar uma única função ou classe para trabalhar com diferentes tipos de dados usando modelos.
Os modelos são freqüentemente usados em uma base de código maior para fins de reutilização de código e flexibilidade dos programas.
O conceito de modelos pode ser usado de duas maneiras diferentes:
- Modelos de função
- Modelos de classes
Modelos de função
Um modelo de função funciona de forma semelhante a uma função normal, com uma diferença fundamental.
Um único modelo de função pode funcionar com diferentes tipos de dados ao mesmo tempo, mas uma única função normal só pode funcionar com um conjunto de tipos de dados.
Normalmente, se você precisa executar operações idênticas em dois ou mais tipos de dados, você usa a sobrecarga de função para criar duas funções com a declaração de função necessária.
No entanto, uma abordagem melhor seria usar modelos de função porque você pode executar a mesma tarefa escrevendo menos código sustentável.
Como declarar um template de função?
Um template de função começa com o template de palavra-chave seguido pelo parâmetro / s do template dentro do qual é seguido pela declaração da função.
template < classe T> T someFunction (T arg) (…)
No código acima, T é um argumento de modelo que aceita diferentes tipos de dados (int, float) e class é uma palavra-chave.
Você também pode usar palavra-chave em typename
vez de classe no exemplo acima.
Quando, um argumento de um tipo de dados é passado para someFunction( )
, o compilador gera uma nova versão de someFunction()
para o tipo de dados fornecido.
Exemplo 1: modelo de função para encontrar o maior número
Programa para exibir o maior entre dois números usando modelos de funções.
// If two characters are passed to function template, character with larger ASCII value is displayed. #include using namespace std; // template function template T Large(T n1, T n2) ( return (n1> n2) ? n1 : n2; ) int main() ( int i1, i2; float f1, f2; char c1, c2; cout <> i1>> i2; cout << Large(i1, i2) <<" is larger." << endl; cout <> f1>> f2; cout << Large(f1, f2) <<" is larger." << endl; cout <> c1>> c2; cout << Large(c1, c2) << " has larger ASCII value."; return 0; )
Resultado
Insira dois inteiros: 5 10 10 é maior. Insira dois números de ponto flutuante: 12,4 10,2 12,4 é maior. Insira dois caracteres: z Z z tem um valor ASCII maior.
No programa acima, Large()
é definido um modelo de função que aceita dois argumentos n1 e n2 do tipo de dados T
. T
significa que o argumento pode ser de qualquer tipo de dados.
Large()
função retorna o maior entre os dois argumentos usando uma operação condicional simples.
Dentro da main()
função, variáveis de três tipos de dados diferentes: int
, float
e char
são declarados. As variáveis são então passadas para o Large()
modelo de função como funções normais.
Durante o tempo de execução, quando um inteiro é passado para a função de modelo, o compilador sabe que deve gerar uma Large()
função para aceitar os argumentos int e assim o faz.
Da mesma forma, quando dados de ponto flutuante e dados char são passados, ele conhece os tipos de dados do argumento e gera a Large()
função de acordo.
Dessa forma, o uso de apenas um único modelo de função substituiu três funções normais idênticas e tornou seu código sustentável.
Exemplo 2: trocar dados usando modelos de função
Programa para trocar dados usando modelos de função.
#include using namespace std; template void Swap(T &n1, T &n2) ( T temp; temp = n1; n1 = n2; n2 = temp; ) int main() ( int i1 = 1, i2 = 2; float f1 = 1.1, f2 = 2.2; char c1 = 'a', c2 = 'b'; cout << "Before passing data to function template."; cout << "i1 = " << i1 << "i2 = " << i2; cout << "f1 = " << f1 << "f2 = " << f2; cout << "c1 = " << c1 << "c2 = " << c2; Swap(i1, i2); Swap(f1, f2); Swap(c1, c2); cout << "After passing data to function template."; cout << "i1 = " << i1 << "i2 = " << i2; cout << "f1 = " << f1 << "f2 = " << f2; cout << "c1 = " << c1 << "c2 = " << c2; return 0; )
Resultado
Antes de passar os dados para o modelo de função. i1 = 1 i2 = 2 f1 = 1,1 f2 = 2,2 c1 = a c2 = b Depois de passar os dados para o modelo de função. i1 = 2 i2 = 1 f1 = 2,2 f2 = 1,1 c1 = b c2 = a
Neste programa, em vez de chamar uma função passando um valor, uma chamada por referência é emitida.
O Swap()
template da função pega dois argumentos e os troca por referência.
Modelos de classes
Como os modelos de função, você também pode criar modelos de classe para operações de classe genéricas.
Às vezes, você precisa de uma implementação de classe que seja a mesma para todas as classes, apenas os tipos de dados usados são diferentes.
Normalmente, você precisaria criar uma classe diferente para cada tipo de dados OU criar diferentes variáveis de membro e funções dentro de uma única classe.
Isso vai inchar desnecessariamente sua base de código e será difícil de manter, pois uma mudança é uma classe / função que deve ser executada em todas as classes / funções.
No entanto, os modelos de classe facilitam a reutilização do mesmo código para todos os tipos de dados.
Como declarar um modelo de classe?
template < class T> class className (… public: T var; T someOperation (T arg);…);
Na declaração acima, T
é o argumento do modelo que é um espaço reservado para o tipo de dados usado.
Dentro do corpo da classe, uma variável-membro var e uma função-membro someOperation()
são do tipo T
.
Como criar um objeto de modelo de classe?
Para criar um objeto de modelo de classe, você precisa definir o tipo de dados dentro de um quando a criação.
className classObject;
Por exemplo:
className classObject; className classObject; className classObject;
Exemplo 3: calculadora simples usando modelo de classe
Programa para adicionar, subtrair, multiplicar e dividir dois números usando o modelo de classe
#include using namespace std; template class Calculator ( private: T num1, num2; public: Calculator(T n1, T n2) ( num1 = n1; num2 = n2; ) void displayResult() ( cout << "Numbers are: " << num1 << " and " << num2 << "." << endl; cout << "Addition is: " << add() << endl; cout << "Subtraction is: " << subtract() << endl; cout << "Product is: " << multiply() << endl; cout << "Division is: " << divide() << endl; ) T add() ( return num1 + num2; ) T subtract() ( return num1 - num2; ) T multiply() ( return num1 * num2; ) T divide() ( return num1 / num2; ) ); int main() ( Calculator intCalc(2, 1); Calculator floatCalc(2.4, 1.2); cout << "Int results:" << endl; intCalc.displayResult(); cout << endl << "Float results:" << endl; floatCalc.displayResult(); return 0; )
Resultado
Resultados Int: Os números são: 2 e 1. A adição é: 3 A subtração é: 1 O produto é: 2 A divisão é: 2 Resultados flutuantes: Os números são: 2,4 e 1,2. A adição é: 3,6 A subtração é: 1,2 O produto é: 2,88 A divisão é: 2
No programa acima, um modelo de classe Calculator
é declarado.
A classe contém dois membros privados do tipo T
: num1 e num2 e um construtor para inicializar os membros.
Ele também contém funções de membro público para calcular a adição, subtração, multiplicação e divisão dos números que retornam o valor do tipo de dados definido pelo usuário. Da mesma forma, uma função displayResult()
para exibir a saída final na tela.
Na main()
função, dois Calculator
objetos diferentes intCalc
e floatCalc
são criados para tipos de dados: int
e float
respectivamente. Os valores são inicializados usando o construtor.
Observe que usamos e
ao criar os objetos. Eles informam ao compilador o tipo de dados usado para a criação da classe.
Isso cria uma definição de classe para cada int
e float
, que é então usada de acordo.
Em seguida, o displayResult()
de ambos os objetos é chamado, o que realiza as operações da Calculadora e exibe a saída.