Définir un modèle de fonction. Prototype de modèle de fonction. Création d'un modèle de fonction simple

Nous avons déjà envisagé un outil tel que les modèles en C++ lorsque nous avons créé . La raison pour laquelle vous devriez utiliser des modèles a été écrite dans l'article avec les modèles de fonctions. Nous y avons examiné les dispositions de base des modèles en C++. Souvenons-nous d'eux.

Tout modèle commence par le mot modèle, qu'il s'agisse d'un modèle de fonction ou d'un modèle de classe. Le mot-clé du modèle est suivi de crochets angulaires -< >, qui répertorie une liste de paramètres de modèle. Chaque paramètre doit être précédé du mot réservé class ou typename . L'absence de ces mots-clés sera interprétée par le compilateur comme . Quelques exemples de déclarations de modèles :

Modèle

Modèle

Modèle

Le mot-clé typename indique au compilateur que le modèle utilisera un type de données intégré tel que : int , double , float , char , etc. Et le mot-clé class indique au compilateur que le modèle de fonction utilisera des types de données personnalisés comme paramètre , c'est-à-dire des cours. Mais ne confondez en aucun cas un paramètre de modèle avec un modèle de classe. Si nous devons créer un modèle de classe avec un paramètre de type int et char , le modèle de classe ressemblera à ceci :

Modèle

où T est un paramètre de modèle de classe qui peut accepter n'importe quel type de données intégré, ce dont nous avons besoin.

Et si le paramètre du modèle de classe doit être d'un type personnalisé, tel que Array , où Array est une classe qui décrit un tableau, le modèle de classe ressemblera à ceci :

Modèle Nom de la classe ( //corps du modèle de classe );

Il est préférable que vous compreniez cela dès le début afin qu'aucune erreur ne survienne plus tard, même si le modèle de classe est écrit correctement.

Créons un modèle de classe Stack, où , qui stocke des éléments de données similaires. Vous pouvez pousser et insérer des données sur la pile. Un élément ajouté à la pile est placé en haut de la pile. Les éléments de la pile sont supprimés en commençant par le haut. Dans le modèle de classe Stack, vous devez créer les méthodes principales :

  • Pousser— ajouter un élément à la pile ;
  • Populaire- supprimer un élément de la pile
  • imprimerStack— afficher la pile sur l'écran ;

Implémentons donc ces trois méthodes, et à la fin nous obtiendrons la classe la plus simple qui implémente le fonctionnement de la structure de pile. N'oubliez pas les constructeurs et les destructeurs. Voir le code ci-dessous.

#include "stdafx.h" #include modèle << "Заталкиваем элементы в стек: "; int ct = 0; while (ct++ != 5) { int temp; cin >> << "\nУдаляем два элемента из стека:\n"; myStack.pop(); // удаляем элемент из стека myStack.pop(); // удаляем элемент из стека myStack.printStack(); // вывод стека на экран return 0; } // конструктор template Empiler ::Stack(int s) ( taille = s > Empiler booléen Pile booléen Pile pile vide ::printStack() ( pour (int ix = taille -1; ix >= 0; ix--) cout<< "|" << setw(4) << stackPtr << endl; }

// code Code :: Blocs

// Code Dev-C++

#inclure en utilisant l'espace de noms std ; #inclure modèle class Stack ( private: T *stackPtr; // pointeur vers la pile int size; // taille de la pile T top; // haut de la pile public: Stack(int = 10); // par défaut la taille de la pile est de 10 éléments ~Stack() ; // destructeur bool push(const T); // pousse un élément sur la pile bool pop( // supprime un élément de la pile void printStack()); int main() ( Pile maPile(5);<< "Заталкиваем элементы в стек: "; int ct = 0; while (ct++ != 5) { int temp; cin >// remplit la pile<< "\nУдаляем два элемента из стека:\n"; myStack.pop(); // удаляем элемент из стека myStack.pop(); // удаляем элемент из стека myStack.printStack(); // вывод стека на экран return 0; } // конструктор template Empiler > température ; Empiler maStack.push(temp); booléen Pile ) maStack.printStack(); // imprime la pile sur l'écran booléen Pile ::Stack(int s) ( size = s > 0 ? s: 10; // initialise la taille de la pile stackPtr = new T; // alloue de la mémoire pour la pile top = -1; // la valeur -1 indique que la pile vide ) // destructeur de modèle pile vide ::printStack() ( pour (int ix = taille -1; ix >= 0; ix--) cout<< "|" << setw(4) << stackPtr << endl; }

::~Stack() ( delete stackPtr; // supprime la pile ) // l'élément est une fonction de la classe Stack permettant de placer un élément sur la pile // la valeur de retour est vraie, l'opération s'est terminée avec succès // faux, l'élément n'a pas été ajouté au modèle de pile

::push(const T value) ( ​​​​if (top == size - 1) return false; // la pile est pleine top++; stackPtr = value; // pousser l'élément sur la pile return true; // réussite de l'opération) // fonction de l'élément Classe Stack pour supprimer un élément de la pile // la valeur de retour est vraie, l'opération s'est terminée avec succès // faux, la pile est un modèle vide ::pop() ( if (top == - 1) return false; // la pile est vide stackPtr = 0; // supprime un élément du haut de la pile--; return true; // réussite de l'opération ) // affiche la pile sur le modèle d'écran Comme vous pouvez le voir, le modèle de classe Stack est déclaré et défini dans le fichier avec la fonction principale. Bien sûr, cette méthode de recyclage des modèles n’est pas bonne, mais elle fera l’affaire à titre d’exemple. Les lignes 7 à 20 déclarent l'interface du modèle de classe. La déclaration de classe se fait de la manière habituelle, et avant la classe il y a une déclaration de modèle, à la ligne 7. Lors de la déclaration d'un modèle de classe, utilisez toujours cette syntaxe.

Pour lier chaque élément de fonction à un modèle de classe, comme d'habitude nous utilisons l'opération de résolution de portée binaire - :: avec le nom du modèle de classe - Stack . C'est ce que nous avons fait aux lignes 49, 58, 68, 83, 96.

Notez la déclaration de l'objet myStack du modèle de classe Stack dans la fonction principale, ligne 24. Les crochets angulaires doivent indiquer explicitement le type de données utilisé ; cela n'était pas nécessaire dans les modèles de fonctions. Ensuite, main exécute certaines fonctions qui démontrent le fonctionnement du modèle de classe Stack. Le résultat du programme est présenté ci-dessous.

On pousse les éléments sur la pile : 12 3456 768 5 4564 |4564 | 5 | 768 |3456 | 12 Supprimez deux éléments de la pile : | 0 | 0 | 768 |3456 | 12

J'étais sur le point d'écrire un texte sur toutes sortes de structures de données intéressantes, puis il s'est avéré que nous n'avions pas encore examiné plusieurs fonctionnalités très importantes du C++. Les modèles en font partie.

Les modèles sont un outil très puissant. Les fonctions et classes de modèles peuvent grandement simplifier la vie d'un programmeur et lui faire gagner énormément de temps, d'efforts et de nerfs. Si vous pensez que les modèles ne sont pas un sujet très important à étudier, sachez que vous vous trompez.

Fonctions du modèle

Un exemple simple de fonction de modèle :

code en langage C++ Tapez carré (Type a) ( Type b; b = a*a; return b; ) int x = 5; int je; je = carré(5); flottant y = 0,5 ; flotter f; f = carré(y);

Si nous créions des fonctions à l’ancienne, nous devrions alors écrire deux fonctions différentes : pour le type int et pour le type float. Et si vous aviez besoin de la même fonction en utilisant d’autres types, vous devrez la réécrire. À l'aide de modèles, vous pouvez vous limiter à une seule instance d'une fonction, laissant tout le sale boulot au compilateur.

Au lieu d'utiliser un type spécifique, la fonction utilise un type paramétrique (ou, en d'autres termes, un argument de modèle). Ici, j'ai appelé le type paramétrique l'identifiant Type. Cet identifiant apparaît trois fois dans une fonction : la valeur de retour, l'argument de la fonction et la définition de la variable s. Autrement dit, Type est utilisé comme n’importe quel type normal.

Mais pour que le code fonctionne, il faut ajouter la ligne suivante avant la fonction (j'ai montré plusieurs options de syntaxe, elles fonctionnent toutes) :

code en langage C++ modèle Modèle de type carré (Type a) < class Type >Modèle de type carré (Type a)< class Type >Type carré (Type a)

Ainsi, la fonction doit être précédée du modèle de mot-clé, et entre crochets vous devez spécifier le nom du type paramétrique avec la classe de mot-clé. Au lieu du mot-clé class, vous pouvez utiliser type - en général, il n'y a aucune différence.

L'identifiant de type paramétrique peut également être n'importe quoi. Nous utiliserons souvent ceux-ci : TypeA, TypeB, Datatype, T.

Remarque importante: Les fonctions de modèle doivent avoir un argument pour que le compilateur puisse déterminer le type à utiliser.

Vous pouvez utiliser plusieurs types paramétriques dans les modèles, et bien sûr, vous pouvez mélanger des types paramétriques avec des types standard (il vous suffit de veiller à la conversion de type correcte). Je vais donner un exemple qui utilise deux types paramétriques TypeA, TypeB et le type de base int :

code en langage C++ modèle Exemple_fonction de type B (TypeA a, TypeB b) ( int x = 5; b = a + x; return b; )

Mais les fonctions de modèle ne sont pas la chose la plus intéressante que nous examinerons aujourd'hui.

Classes de modèles

En général, les classes modèles sont créées de la même manière que les fonctions modèles : le mot-clé template est écrit avant le nom de la classe. Examinons les classes de modèles en utilisant l'exemple d'une pile :

code en langage C++ modèle pile de classes ( private: int top; Tapez s; public: stack (): top(0) () void push(Type var) ( top++; s = var; ) Tapez pop(); ); modèle Tapez stack::pop() ( Tapez var = s; top--; return var; ) Ici, nous définissons

partagé une pile de dix éléments. Ces éléments peuvent être de n’importe quel type, nous en parlerons ci-dessous.

La seule chose sur laquelle je souhaite attirer votre attention est la définition des fonctions push et pop. La fonction push est définie à l'intérieur de la classe et la fonction pop est définie à l'extérieur. Pour toutes les fonctions déclarées en dehors de la classe, le mot-clé template doit être spécifié. L'expression avant le nom de la fonction est la même que celle avant le nom de la classe.

Voyons maintenant comment travailler avec les classes modèles :

code en langage C++ empiler s1 ; empiler s2 ; s1.push(3); s1.push(2); s1.pop(); s2.push(0.5);

Lors de la création d'un objet, après le nom de la classe, vous devez mettre des crochets angulaires pour indiquer le type souhaité. Après cela, les objets sont utilisés comme nous en avons l’habitude.

Les classes de modèles ont une fonctionnalité étonnante : en plus des types standard, elles peuvent également fonctionner avec des types personnalisés. Regardons un petit exemple. Pour ce faire, définissons une classe de guerrier simple :

code en langage C++ guerrier de classe ( public: int santé; guerrier () : santé(0) () ); empiler s ; guerrier w1; guerrier w2; guerrier w3; s.push(w1); s.push(w3); s.pop(); s.push(w2);

Regardez, maintenant vous pouvez mettre des variables de type guerrier sur des piles !!! Vous ne me croyez peut-être pas, mais c'est très cool ! Vous pouvez voir à quel point c'est cool lorsque nous créons des graphiques et des arbres basés sur des listes.

Tout est conforme aux modèles pour l'instant. Nous examinerons plus tard des cas plus complexes d'utilisation de classes modèles.

Une fonction modèle définit un ensemble général d'opérations qui seront appliquées à différents types de données. Grâce à ce mécanisme, il est possible d’appliquer certains algorithmes généraux à un large éventail de données. Comme vous le savez, de nombreux algorithmes sont logiquement les mêmes quel que soit le type de données avec lesquels ils fonctionnent. Par exemple, l'algorithme de tri rapide est le même pour un tableau d'entiers et un tableau de nombres à virgule flottante. Seul le type de données à trier diffère. En créant une fonction générique, vous pouvez définir l'essence de l'algorithme quel que soit le type de données. Après cela, le compilateur génère automatiquement le code correct pour le type de données pour lequel cette implémentation particulière de la fonction est créée au stade de la compilation. Essentiellement, lorsqu'une fonction modèle est créée, elle crée une fonction qui peut automatiquement se surcharger.

Les fonctions de modèle sont créées à l'aide du mot-clé template. Le sens habituel du mot « modèle » reflète assez pleinement son utilisation en C++. Un modèle est utilisé pour créer le squelette d'une fonction, laissant les détails d'implémentation au compilateur. La forme générale d'une fonction modèle est la suivante :

modèle return_type function_name (liste de paramètres)
{
// corps de la fonction
}

Ici, ptype est un paramètre de type, un « espace réservé » pour le nom du type de données utilisé par la fonction. Ce paramètre de type peut être utilisé dans une définition de fonction. Cependant, il ne s'agit que d'un "espace réservé" qui sera automatiquement remplacé par le compilateur par le type de données réel lorsqu'une version particulière de la fonction est créée.

Vous trouverez ci-dessous un court exemple qui crée une fonction de modèle comportant deux paramètres. Cette fonction modifie les valeurs de ces paramètres entre elles. Étant donné que le processus général d'échange de valeurs entre deux variables ne dépend pas de leur type, il peut être naturellement implémenté à l'aide d'une fonction modèle.

// exemple de modèle de fonction
#inclure
// modèle de fonction
modèle échange nul (X &a, X &b)
{
Température X ;
température = a;
une = b;
b = température ;
}
int principal()
{
int je = 10, j = 20 ;
flotteur x=10,1, y= 23,3 ;
char a="x", b="z";
cout<< "Original i, j: " << i << " " << j << endl;
cout<< "Original x, y: " << x << " " << у << endl;
cout<< "Original a, b: " << a << " " << b << endl;
échanger(je, j); // échange d'entiers
échanger(x, y); // échange de valeurs réelles
échanger(a, b); // échange de caractères
cout<< "Swapped i, j: " << i << " " << j << endl;
cout<< "Swapped x, y: " << x << " " << у << endl;
cout<< "Swapped a, b: " << a << " " << b << endl;
renvoie 0 ;
}

Regardons de plus près ce programme. Doubler

Modèle échange nul (X &a, X &b)

Indique au compilateur qu'un modèle est en cours de génération. Ici, X est le modèle de type utilisé comme paramètre de type. Vient ensuite la déclaration de la fonction swap(), utilisant le type de données X pour les paramètres qui échangeront des valeurs. Dans la fonction main(), la fonction swap() est appelée avec trois types de données différents qui lui sont transmis : des entiers, des nombres à virgule flottante et des caractères. Étant donné que la fonction swap() est une fonction modèle, le compilateur créera automatiquement trois versions différentes de la fonction swap() : une pour travailler avec des entiers, une autre pour travailler avec des nombres à virgule flottante et enfin une troisième pour travailler avec des variables de caractères.

Vous pouvez prototyper un modèle de fonction en le pré-déclarant.

Cette déclaration informe le compilateur de la présence du modèle et informe également le compilateur des paramètres attendus. Par exemple, le prototype du modèle de fonction Sort ressemblerait à ceci : modèle

void Sort (tableau T, taille Tsize);

Cette déclaration informe le compilateur de la présence du modèle et informe également le compilateur des paramètres attendus. Par exemple, le prototype du modèle de fonction Sort ressemblerait à ceci : Les noms des paramètres formels d'un modèle peuvent ne pas être les mêmes dans la pré-déclaration et la définition du modèle. Ainsi, par exemple, dans l'extrait suivant, le prototype du modèle et la définition du modèle font référence à la même fonction :

Cette déclaration informe le compilateur de la présence du modèle et informe également le compilateur des paramètres attendus. Par exemple, le prototype du modèle de fonction Sort ressemblerait à ceci :

Tmax(T,T);

Type max (Type a, Type b)

si (a > b) renvoie a ; sinon, retourne b;

Utilisation d'un modèle de fonction Un modèle de fonction décrit comment une fonction particulière peut être construite sur la base d'un ou plusieurs types réels. Le compilateur crée automatiquement un corps de fonction représentatif pour les types spécifiés dans l'appel. Ce processus est appelé spécification

.

Cette déclaration informe le compilateur de la présence du modèle et informe également le compilateur des paramètres attendus. Par exemple, le prototype du modèle de fonction Sort ressemblerait à ceci :

Cela se produit lorsqu'une fonction de modèle est appelée.

Par exemple, dans l'exemple suivant, la fonction min() est instanciée deux fois : une fois avec le type int et une fois avec le type double :< b) return a; else return b;

Tapez min (Type a, Type b)

si (un

int x = 4, y = 5, z ;

doublet = 6,56, r = 3,07, p ;

Cette déclaration informe le compilateur de la présence du modèle et informe également le compilateur des paramètres attendus. Par exemple, le prototype du modèle de fonction Sort ressemblerait à ceci :

Cela se produit lorsqu'une fonction de modèle est appelée.

Par exemple, dans l'exemple suivant, la fonction min() est instanciée deux fois : une fois avec le type int et une fois avec le type double :< b) return a; else return b;

Spécialisation des modèles de fonctions

Une fonction de modèle spécialisée est une fonction régulière dont le nom est le même que celui de la fonction dans le modèle, mais qui est définie pour des paramètres de types spécifiques.

Les fonctions de modèle spécialisées sont définies lorsqu'un modèle générique ne convient pas à un type de données particulier. Par exemple, la fonction modèle min

Vous pouvez alors accéder à une telle fonction de la même manière qu’une fonction modèle :

int i1 = 3, i2 = 5 ;

cout<< “max int = ” << max(i1, i2) << endl;

char* s1 = « Aigle royal » ;

char* s2 = « Faucon pèlerin » ;

cout<< “max str = “ << max(s1, s2) << endl;

Modèles de cours

Modèle de classe donne une définition générale d'une famille de classes utilisant des types ou des constantes arbitraires. Le motif définit membres de données de modèle Et fonctions des membres du modèle.

Une fois qu'un modèle de classe a été défini, vous pouvez demander au compilateur de générer une nouvelle classe basée sur celui-ci pour un type ou une constante spécifique.

Cette déclaration informe le compilateur de la présence du modèle et informe également le compilateur des paramètres attendus. Par exemple, le prototype du modèle de fonction Sort ressemblerait à ceci :<<список аргументов шаблона>>

Syntaxe du modèle de classe<имя класса>

<тело класса>

classe

Le mot-clé template est suivi d'un ou plusieurs arguments (paramètres) entourés de crochets angulaires et séparés par des virgules. Chaque argument peut être un mot-clé de classe suivi d'un identifiant indiquant le type paramétré.

La liste des arguments du modèle ne peut pas être vide. Vient ensuite la définition de la classe. C'est similaire à la définition d'une classe normale, sauf qu'elle utilise une liste d'arguments de modèle. Les paramètres de modèle constitués du mot-clé class suivi d'un identifiant sont souvent appelés

paramètres de type

.

En d’autres termes, ils informent le compilateur que le modèle attend un type comme argument.

En d’autres termes, les modèles de fonctions sont des instructions selon lesquelles des versions locales d’une fonction basée sur un modèle sont créées pour un ensemble spécifique de paramètres et de types de données.< count; ix++) cout << array << " "; cout << endl; } void printArray(const double * array, int count) { for (int ix = 0; ix < count; ix++) cout << array << " "; cout << endl; } void printArray(const float * array, int count) { for (int ix = 0; ix < count; ix++) cout << array << " "; cout << endl; } void printArray(const char * array, int count) { for (int ix = 0; ix < count; ix++) cout << array << " "; cout << endl; }

En fait, les modèles de fonctions sont un outil puissant en C++ qui facilite grandement le travail d'un programmeur. Par exemple, nous devons programmer une fonction qui afficherait les éléments d’un tableau. La tâche n'est pas difficile ! Mais pour écrire une telle fonction, il faut connaître le type de données du tableau que l’on va afficher à l’écran. Et puis ils nous disent : il y a plus d'un type de données, nous voulons que la fonction génère des tableaux de types int, double, float et char.

Et si vous exécutez le programme avec ces fonctions, il fonctionnera correctement. Le compilateur lui-même déterminera quelle fonction utiliser lors de l'appel.

Comme vous pouvez le constater, il y avait beaucoup de code pour une opération aussi simple. Et si nous devions le programmer en fonction. Il s'avère que pour chaque type de données, vous devrez créer votre propre fonction. C'est-à-dire que vous comprenez vous-même que le même code sera en plusieurs exemplaires, cela ne nous est d'aucune utilité. C'est pourquoi C++ a mis au point un tel mécanisme : les modèles de fonctions.

Nous créons un modèle dans lequel nous décrivons tous les types de données. De cette façon, la source ne sera pas encombrée de lignes de code inutiles. Ci-dessous, nous examinerons un exemple de programme avec un modèle de fonction. Rappelons donc la condition : « programmer une fonction qui afficherait les éléments du tableau ».

#inclure < count; ix++) cout << array << " "; cout << endl; } // конец шаблона функции printArray int main() { // размеры массивов const int iSize = 10, dSize = 7, fSize = 10, cSize = 5; // массивы разных типов данных int iArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double dArray = {1.2345, 2.234, 3.57, 4.67876, 5.346, 6.1545, 7.7682}; float fArray = {1.34, 2.37, 3.23, 4.8, 5.879, 6.345, 73.434, 8.82, 9.33, 10.4}; char cArray = {"MARS"}; cout << "\t\t Шаблон функции вывода массива на экран\n\n"; // вызов локальной версии функции printArray для типа int через шаблон cout << "\nМассив типа int:\n"; printArray(iArray, iSize); // вызов локальной версии функции printArray для типа double через шаблон cout << "\nМассив типа double:\n"; printArray(dArray, dSize); // вызов локальной версии функции printArray для типа float через шаблон cout << "\nМассив типа float:\n"; printArray(fArray, fSize); // вызов локальной версии функции printArray для типа char через шаблон cout << "\nМассив типа char:\n";printArray(cArray, cSize); return 0; }

// code Code :: Blocs

// Code Dev-C++

#inclure #inclure en utilisant l'espace de noms std ; // modèle de fonction modèle printArray void printArray(const T * array, int count) ( pour (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; } // конец шаблона функции printArray int main() { // размеры массивов const int iSize = 10, dSize = 7, fSize = 10, cSize = 5; // массивы разных типов данных int iArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double dArray = {1.2345, 2.234, 3.57, 4.67876, 5.346, 6.1545, 7.7682}; float fArray = {1.34, 2.37, 3.23, 4.8, 5.879, 6.345, 73.434, 8.82, 9.33, 10.4}; char cArray = {"MARS"}; cout << "\t\t Шаблон функции вывода массива на экран\n\n"; // вызов локальной версии функции printArray для типа int через шаблон cout << "\nМассив типа int:\n"; printArray(iArray, iSize); // вызов локальной версии функции printArray для типа double через шаблон cout << "\nМассив типа double:\n"; printArray(dArray, dSize); // вызов локальной версии функции printArray для типа float через шаблон cout << "\nМассив типа float:\n"; printArray(fArray, fSize); // вызов локальной версии функции printArray для типа char через шаблон cout << "\nМассив типа char:\n";printArray(cArray, cSize); return 0; }

Veuillez noter que le code a été réduit de 4 fois, puisqu'une seule instance de la fonction est déclarée dans le programme - le modèle. Dans main, j'ai déclaré plusieurs tableaux - quatre, pour les types de données : int, double, float, char. Après quoi, aux lignes 26, 28, 30, 32, la fonction printArray est appelée pour différents tableaux. Le résultat du programme est présenté ci-dessous.

Modèle d'affichage d'un tableau à l'écran Tableau de type int : 1 2 3 4 5 6 7 8 9 10 Tableau de type double : 1.2345 2.234 3.57 4.67876 5.346 6.1545 7.7682 Tableau de type float : 1.34 2.37 3.23 4.8 5.879 6. 345 73,434 8,82 9.33 10.4 Tableau de type char : M A R S

Comme vous pouvez le constater, le programme fonctionne correctement, et pour cela il nous suffit de définir une seule fois la fonction printArray sous la forme qui nous est familière. Veuillez noter qu'avant la déclaration de la fonction elle-même, à la ligne 5, il y a l'entrée de modèle suivante . Cette entrée suggère que la fonction printArray est en fait un modèle de fonction, puisque le premier paramètre de printArray contient un type de données const T*, exactement le même qu'à la ligne 5.

Tous les modèles de fonctions commencent par le mot modèle suivi de crochets qui répertorient les paramètres. Chaque paramètre doit être précédé du mot réservé class ou typename .

Modèle

Modèle

Modèle

Le mot-clé typename indique au compilateur que le modèle utilisera un type de données intégré tel que : int , double , float , char , etc. Et le mot-clé class indique au compilateur que le modèle de fonction utilisera des types de données personnalisés comme paramètre , c'est-à-dire des cours.

Notre modèle de fonction utilisait des types de données intégrés, donc à la ligne 5 nous avons écrit un modèle . Au lieu de T, vous pouvez remplacer n’importe quel autre nom auquel vous pouvez penser. Examinons de plus près le fragment de code du programme principal, je le publierai séparément.

// modèle de fonction modèle printArray void printArray(const T * array, int count) ( pour (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; } // конец шаблона функции printArray

La ligne 2 définit un modèle avec un paramètre, T, et ce paramètre aura l'un des types de données intégrés car le mot-clé typename est spécifié.

Ci-dessous, aux lignes 3 à 8, une fonction est déclarée qui répond à tous les critères de déclaration d'une fonction régulière, il y a un en-tête, il y a un corps de fonction, l'en-tête contient le nom et les paramètres de la fonction, tout est comme d'habitude. Mais ce qui transforme cette fonction en modèle de fonction, c'est un paramètre de type de données T , qui est la seule connexion au modèle déclaré précédemment. Si on écrivait

Void printArray(const int * array, int count) ( pour (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; }

alors ce serait une fonction simple pour un tableau de type int .

Donc, en fait, T n'est même pas un type de données, c'est une place réservée à tout type de données intégré. Autrement dit, lorsque cette fonction est appelée, le compilateur analyse le paramètre de la fonction basée sur un modèle et crée une instance pour le type de données approprié : int, char, etc.

Par conséquent, vous devez comprendre que même si la quantité de code est inférieure, cela ne signifie pas que le programme consommera moins de mémoire. Le compilateur lui-même crée des copies locales de la fonction modèle et, par conséquent, la quantité de mémoire consommée est comme si vous aviez écrit vous-même toutes les instances de fonction, comme c'est le cas en cas de surcharge.
J'espère vous avoir transmis l'idée principale des modèles de fonctions. Pour renforcer le matériel, regardons un autre exemple de programme utilisant un modèle de fonction.

#include "stdafx.h" #include #inclure < size; ix++) if (max < array) max = array; return max; } int main() { // тестируем шаблон функции searchMax для массива типа char char array = "aodsiafgerkeio"; int len = strlen(array); cout << "Максимальный элемент массива типа char: " << searchMax(array, len) << endl; // тестируем шаблон функции searchMax для массива типа int int iArray = {3,5,7,2,9}; cout << "Максимальный элемент массива типа int: " << searchMax(iArray, 5) << endl; return 0; }

// code Code :: Blocs

// Code Dev-C++

#inclure #inclure en utilisant l'espace de noms std ; // modèle de fonction pour trouver la valeur maximale dans le modèle de tableau T searchMax(const T* array, int size) ( T max = array; // valeur maximale dans le tableau pour (int ix = 0; ix< size; ix++) if (max < array) max = array; return max; } int main() { // тестируем шаблон функции searchMax для массива типа char char array = "aodsiafgerkeio"; int len = strlen(array); cout << "Максимальный элемент массива типа char: " << searchMax(array, len) << endl; // тестируем шаблон функции searchMax для массива типа int int iArray = {3,5,7,2,9}; cout << "Максимальный элемент массива типа int: " << searchMax(iArray, 5) << endl; return 0; }

Voici un autre exemple d'utilisation de modèles de fonctions. Le modèle de fonction est déclaré aux lignes 5 à 13. La fonction doit renvoyer la valeur maximale du tableau, donc la valeur de retour est de type T , car le type de données du tableau n'est pas connu à l'avance. À propos, une variable max de type T est déclarée à l'intérieur de la fonction ; la valeur maximale du tableau y sera stockée. Comme vous pouvez le voir, le type de données T est utilisé non seulement pour spécifier les paramètres de fonction, mais également pour indiquer le type de retour, et peut également être librement utilisé pour déclarer n'importe quelle variable dans un modèle de fonction.

Élément maximum d'un tableau de type char : s Élément maximum d'un tableau de type int : 9

Les modèles de fonctions peuvent également être surchargés avec d'autres modèles de fonctions en modifiant le nombre de paramètres transmis à la fonction. Une autre caractéristique de la surcharge est que les fonctions de modèle peuvent être surchargées avec des fonctions normales non-modèles. Autrement dit, le même nom de fonction est spécifié, avec les mêmes paramètres, mais pour un type de données spécifique, et tout fonctionnera correctement.



Des questions ?

Signaler une faute de frappe

Texte qui sera envoyé à nos rédacteurs :