Como usar modelos C ++

Como usar modelos C ++
Na programação básica de C ++, o tipo de dados, e.g., int ou char, deve ser indicado em uma declaração ou definição. Um valor como 4 ou 22 ou -5 é um int. Um valor como 'a' ou 'b' ou 'c' é um char. O mecanismo de modelo permite que o programador use um tipo genérico para um conjunto de tipos reais. Por exemplo, o programador pode decidir usar o identificador t para int ou char. É possível que um algoritmo C ++ tenha mais de um tipo genérico. Com, digamos, t para o int ou char, você pode representar o tipo de flutuação ou ponteiro. Uma classe, como a classe String ou vetor. Portanto, o mecanismo de modelo também permite que o programador use um identificador de tipo genérico para um conjunto de classes.

Um modelo C ++ cria um algoritmo independente do tipo de dados empregados. Portanto, o mesmo algoritmo, com muitas ocorrências do mesmo tipo, pode usar diferentes tipos em diferentes execuções. As entidades de variável, função, estrutura e classe podem ter modelos. Este artigo explica como declarar modelos, como definir modelos e como aplicá -los em c++. Você já deve ter conhecimento das entidades acima mencionadas para entender os tópicos abordados neste artigo.

Tipos

Escalar

Os tipos escalares são nulos, bool, char, int, float e ponteiro.

Classes como tipos

Uma classe específica pode ser considerada como um tipo e seus objetos como possíveis valores.

Um tipo genérico representa um conjunto de tipos escalares. A lista de tipos escalares é extensa. O tipo int, por exemplo, possui outros tipos relacionados, como curto int, long int, etc. Um tipo genérico também pode representar um conjunto de classes.

Variável

Um exemplo de uma declaração e definição de modelo é a seguinte:

modelo T pi = 3.14;

Antes de continuar, observe que esse tipo de afirmação não pode aparecer na função principal () ou em qualquer escopo de bloco. A primeira linha é a declaração de cabeça de modelo, com o nome genérico de tipo escolhido por programador, t. A próxima linha é a definição do identificador, pi, que é do tipo genérico, t. Precisão, se o T é um int ou um flutuador ou algum outro tipo, pode ser feito na função C ++ Main (ou alguma outra função). Essa precisão será feita com a variável pi, e não t.

A primeira linha é a declaração da cabeça do modelo. Esta declaração começa com a palavra reservada, modelo e depois os suportes de ângulo aberto e fechado. Dentro dos colchetes do ângulo, há pelo menos um identificador de tipo genérico, como t, acima. Pode haver mais de um identificador de tipo genérico, com cada um precedido pela palavra reservada, tipo de tipo. Tais tipos genéricos nessa posição são chamados de parâmetros de modelo.

A declaração a seguir pode ser escrita em Main () ou em qualquer outra função:

cout << pi << '\n';

E a função exibiria 3.14. A expressão PI decide o tipo exato de t para a variável pi. Especialização decide o tipo de dados específico para o parâmetro de modelo. Instanciação é o processo interno de C ++ de criar o tipo específico, como flutuação, neste caso. Não confunda entre instanciar um parâmetro de modelo e instanciar uma classe. No tópico do modelo, muitos tipos de dados podem ter um nome de tipo genérico, enquanto muitas classes podem ter um nome de classe genérico. No entanto, o nome de classe genérico para as aulas é simplesmente referido como uma classe, e não como um nome de classe. Além disso, um valor é para um tipo de dados, como o INT, como um objeto instanciado é para uma classe, como a classe String.

Na especialização, o tipo de dados escolhido, como o float, é colocado em suportes de ângulo após a variável. Se houver mais de um parâmetro de modelo na declaração de cabeça de modelo, haverá um número correspondente de tipos de dados na mesma ordem na expressão de especialização.

Na especialização, um tipo é conhecido como argumento de modelo. Não confunda entre este e o argumento da função para chamada de função.

Tipo padrão

Se nenhum tipo for dado em especialização, o tipo padrão será assumido. Então, da seguinte expressão:

modelo U pi = "amor";

Esta câmera pode ser usada como tal com um tipo padrão:

cout << pi << '\n';

Em que "Love" para o ponteiro constante para char é usado como padrão do modelo. Nota na declaração de que u = const char*. Os suportes de ângulo estarão vazios na especialização (sem tipo dado); O tipo real é considerado um ponteiro const para char, o tipo padrão. Se algum outro tipo fosse necessário na especialização, o nome do tipo seria escrito nos suportes do ângulo. Quando o tipo padrão é desejado em especialização, repetir o tipo de suportes de ângulo é opcional, i i.e., os suportes de ângulo podem ser deixados vazios.

Nota: o tipo padrão ainda pode ser alterado em especialização, tendo um tipo diferente.

estrutura

O exemplo a seguir mostra como um parâmetro de modelo pode ser usado com uma estrutura:

modelo Estrutura idades

T John = 11;
T Peter = 12;
T Mary = 13;
T alegria = 14;
;

Essas são idades de estudantes em uma série (aula). A primeira linha é a declaração de modelo. O corpo no aparelho é a definição real do modelo. As idades podem ser emitidas na função Main () com o seguinte:

Idades nota 7;
cout << grade7.John << " << grade7.Mary << '\n';

A saída é: 11 13. A primeira declaração aqui executa a especialização. Observe como foi feito. Ele também dá um nome para um objeto da estrutura: grau7. A segunda declaração tem expressões de objeto de estrutura comum. Uma estrutura é como uma classe. Aqui, idades é como um nome de classe, enquanto o grau7 é um objeto da classe (struct).

Se algumas idades são números inteiros e outros são carros alegóricos, a estrutura precisa de dois parâmetros genéricos, como segue:

modelo Estrutura idades

T John = 11;
U Peter = 12.3;
T Mary = 13;
U alegria = 14.6;
;

Um código relevante para a função principal () é o seguinte:

Idades nota 7;
cout << grade7.John << " << grade7.Peter << '\n';

A saída é: 11 12.3. Na especialização, a ordem dos tipos (argumentos) deve corresponder à ordem dos tipos genéricos na declaração.

A declaração de modelo pode ser separada da definição, como segue:

modelo Estrutura idades

T John;
U Pedro;
T Mary;
Você alegria;
;
Idades grau7 = 11, 12.3, 13, 14.6;

O primeiro segmento de código é puramente uma declaração de um modelo (não há tarefas). O segundo segmento de código, que é apenas uma declaração, é a definição do identificador, grau7. O lado esquerdo é a declaração do identificador, grau7. O lado direito é a lista de inicializadores, que atribui valores correspondentes aos membros da estrutura. O segundo segmento (instrução) pode ser escrito na função Main (), enquanto o primeiro segmento permanece fora da função principal ().

Não-tipo

Exemplos de tipos não de dados incluem o INT, o ponteiro de objeto, o ponteiro para funcionar e os tipos de automóveis. Existem outros não-tipos, que este artigo não aborda. Um não-tipo é como um tipo incompleto, cujo valor é dado posteriormente e não pode ser alterado. Como parâmetro, começa com um determinado não-tipo, seguido por um identificador. O valor do identificador é dado posteriormente, em especialização, e não pode ser alterado novamente (como uma constante, cujo valor é dado mais tarde). O programa a seguir ilustra o seguinte:

#incluir
usando namespace std;
modelo Estrutura idades

T John = n;
U Peter = 12.3;
T Mary = n;
U alegria = 14.6;
;
int main ()

Idades nota 7;
cout << grade7.John << " << grade7.Joy << '\n';
retornar 0;

Na especialização, o primeiro tipo, int, nos colchetes do ângulo existe mais para a formalidade, para garantir que o número e a ordem dos parâmetros correspondam ao número e ordem dos tipos (argumentos). O valor de n foi dado em especialização. A saída é: 11 14.6.

Especialização parcial

Vamos supor que um modelo tenha quatro tipos genéricos e que, entre os quatro tipos, é necessário dois tipos de padrão. Isso pode ser alcançado usando o construto de especialização parcial, que não emprega o operador de atribuição. Portanto, o construto de especialização parcial fornece valores padrão a um subconjunto de tipos genéricos. No entanto, no esquema de especialização parcial, são necessárias uma classe base (struct) e uma classe de especialização parcial (struct). O programa a seguir ilustra isso para um tipo genérico de dois tipos genéricos:

#incluir
usando namespace std;
// Classe de modelo base
modelo
Estrutura idades

;
// Especialização parcial
modelo
Estrutura idades

T1 John = 11;
flutuar Peter = 12.3;
T1 Mary = 13;
Float alegria = 14.6;
;
int main ()

Idades nota 7;
cout << grade7.John << " << grade7.Joy << '\n';
retornar 0;

Identifique a declaração da classe base e sua definição de classe parcial. A declaração de cabeça de modelo da classe base tem todos os parâmetros genéricos necessários. A declaração da cabeça do modelo da classe de especialização parcial tem apenas o tipo genérico. Há um conjunto extra de colchetes de ângulo usados ​​no esquema que ocorre logo após o nome da classe na definição de especialização parcial. É o que realmente faz a especialização parcial. Possui o tipo padrão e o tipo não-defensor, na ordem escrita na classe base. Observe que o tipo padrão ainda pode receber um tipo diferente na função principal ().

O código relevante na função Main () pode ser o seguinte:

Idades nota 7;
cout << grade7.John << " << grade7.Joy << '\n';

A saída é: 11 14.6.

Pacote de parâmetros de modelo

Um pacote de parâmetros é um parâmetro de modelo que aceita zero ou mais modelos de tipos genéricos para os tipos de dados correspondentes. O parâmetro de pacote de parâmetros começa com o tipo de palavra ou classe de palavra reservada. Isto é seguido por três pontos e depois o identificador para o pacote. O programa a seguir ilustra como um pacote de parâmetros de modelo pode ser usado com uma estrutura:

#incluir
usando namespace std;
modelo Estrutura idades

int john = 11;
flutuar Peter = 12.3;
int mary = 13;
Float alegria = 14.6;
;
int main ()

Idades Série b;
cout << gradeB.John << " << gradeB.Mary << '\n';
Idades gradec;
cout << gradeC.Peter << " << gradeC.Joy << '\n';
Idades classificado;
cout << gradeD.John << " << gradeD.Joy << '\n';
Graduação das idades; // Como padrão
cout << gradeA.John << " << gradeA.Joy << '\n';
retornar 0;

A saída é:

11 13
12.3 14.6
11 14.6
11 14.6

Modelos de função

Os recursos do modelo mencionados acima se aplicam de maneira semelhante aos modelos de função. O programa a seguir mostra uma função com dois parâmetros de modelo genérico e três argumentos:

#incluir
usando namespace std;
modelo void func (t Não, u cha, const char *str)
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()
func (12, '$', "500");
retornar 0;

A saída é a seguinte:

Existem 12 livros no valor de US $ 500 na loja.

Separação do protótipo

A definição da função pode ser separada de seu protótipo, como mostra o seguinte programa:

#incluir
usando namespace std;
modelo Func void (t Não, U Cha, const char *str);
modelo void func (t Não, u cha, const char *str)
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()
func (12, '$', "500");
retornar 0;

Observação: A declaração do modelo de função não pode aparecer na função principal () ou em qualquer outra função.

Sobrecarga

A sobrecarga da mesma função pode ocorrer com diferentes declarações de cabeça de modelo. O programa a seguir ilustra o seguinte:

#incluir
usando namespace std;
modelo void func (t Não, u cha, const char *str)
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

modelo Void Func (t Não, const char *str)
cout << "There are " << no << " books worth $" << str << " in the store." << '\n';

int main ()

func (12, '$', "500");
func (12, "500");
retornar 0;

A saída é:

Existem 12 livros no valor de US $ 500 na loja.

Existem 12 livros no valor de US $ 500 na loja.

Modelos de aula

Os recursos dos modelos mencionados acima se aplicam de maneira semelhante aos modelos de aula. O programa a seguir é a declaração, definição e uso de uma classe simples:

#incluir
usando namespace std;
CLASSE THECLA

público:
int num;
char estático ch;
Void Func (Char Cha, Const Char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

Função de vazio estático (char ch)
if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

Thecla obj;
obj.num = 12;
obj.func ('$', "500");
retornar 0;

A saída é a seguinte:

Existem 12 livros no valor de US $ 500 na loja.

O programa a seguir é o programa acima com uma declaração de cabeça de modelo:

#incluir
usando namespace std;
modelo CLASSE THECLA

público:
T num;
estático u ch;
void func (u cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

Função de vazio estático (u ch)
if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

THECLA obj;
obj.num = 12;
obj.func ('$', "500");
retornar 0;

Em vez da palavra tipo de tipo na lista de parâmetros de modelo, a classe Word pode ser usada. Observe a especialização na declaração do objeto. A saída ainda é a mesma:

Existem 12 livros no valor de US $ 500 na loja.

Separando a declaração

A declaração do modelo de classe pode ser separada do código de classe, como segue:

modelo Classe theCla;
modelo classe thecla
público:
T num;
estático u ch;
void func (u cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

Função de vazio estático (u ch)
if (ch == 'a')
cout << "Official static member function" << '\n';

;

Lidando com membros estáticos

O programa a seguir mostra como acessar um membro estático de dados e uma função estática:

#incluir
usando namespace std;
modelo classe thecla
público:
T num;
estático u ch;
void func (u cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

Função de vazio estático (u cha)
if (ch == 'a')
cout << "Official static member function" << cha << '\n';

;
modelo U thecla:: ch = 'a';
int main ()

THECLA::diversão('.');
retornar 0;

Atribuir um valor a um membro estático de dados é uma declaração e não pode estar em Main (). Observe o uso e as posições dos tipos genéricos e o tipo genérico de dados na declaração de atribuição. Além disso, observe que a função estática do membro de dados foi chamada em main (), com os tipos de dados de modelo real. A saída é a seguinte:

Função oficial do membro estático.

Compilação

A declaração (cabeçalho) e a definição de um modelo devem estar em um arquivo. Isto é, eles devem estar na mesma unidade de tradução.

Conclusão

Os modelos de C ++ produzem um algoritmo independente do tipo de dados empregados. As entidades de variável, função, estrutura e classe podem ter modelos, que envolvem declaração e definição. Criar um modelo também envolve especialização, que é quando um tipo genérico leva um tipo real. A declaração e a definição de um modelo devem estar em uma unidade de tradução.