templates c with examples
Apprenez les différents aspects des modèles en C ++.
Les modèles sont l'une des fonctionnalités les plus puissantes de C ++. Les modèles nous fournissent le code qui est indépendant du type de données.
En d'autres termes, à l'aide de modèles, nous pouvons écrire un code générique qui fonctionne sur n'importe quel type de données. Nous avons juste besoin de passer le type de données en paramètre. Ce paramètre qui passe le type de données est également appelé nom de type.
Dans ce didacticiel, nous explorerons en détail tout sur les modèles et leurs différents aspects.
=> Cliquez ici pour la série de formations Absolute C ++.
Ce que vous apprendrez:
- Que sont les modèles?
- Comment utiliser les modèles / implémentation?
- nom de type Vs. mot-clé de classe
- Instanciation et spécialisation de modèle
- Spécialisation des modèles
- Modèles Variadic C ++
- Conclusion
- lecture recommandée
Que sont les modèles?
Comme mentionné ci-dessus, les modèles sont génériques, c'est-à-dire indépendants du type de données. Les modèles sont principalement utilisés pour assurer la réutilisation du code et la flexibilité des programmes. Nous pouvons simplement créer une fonction simple ou une classe qui prend le type de données comme paramètre et implémenter le code qui fonctionne pour tout type de données.
Par exemple, si nous voulons qu'un algorithme de tri fonctionne pour tous les types de données numériques ainsi que pour les chaînes de caractères, nous allons simplement écrire une fonction qui prend le type de données comme argument et implémenter la technique de tri.
Ensuite, en fonction du type de données (nom du type) qui est passé à l'algorithme de tri, nous pouvons avoir les données triées quel que soit le type de données. De cette façon, nous n'avons pas besoin d'écrire dix algorithmes pour dix types de données.
Ainsi, des modèles peuvent être utilisés dans des applications dans lesquelles nous avons besoin que le code soit utilisable pour plusieurs types de données. Les modèles sont également utilisés dans les applications où la réutilisabilité du code est de première importance.
Comment utiliser les modèles / implémentation?
Les modèles peuvent être implémentés de deux manières:
- En tant que modèle de fonction
- En tant que modèle de classe
Modèle de fonction
Le modèle de fonction ressemble à une fonction normale, mais la seule différence est que la fonction normale ne peut fonctionner que sur un type de données et qu'un code de modèle de fonction peut fonctionner sur plusieurs types de données.
Bien que nous puissions surcharger une fonction normale pour travailler sur divers types de données, les modèles de fonction sont toujours plus utiles car nous devons écrire le seul programme et il peut fonctionner sur tous les types de données.
Ensuite, nous verrons l'implémentation des modèles de fonctions.
La syntaxe générale du modèle de fonction est:
template T function_name(T args){ …… //function body }
Ici, T est l'argument de modèle qui accepte différents types de données et la classe est un mot-clé. Au lieu de la classe de mots-clés, nous pouvons également écrire 'typename'.
Lorsqu'un type de données particulier est passé à nom_fonction, une copie de cette fonction est effectuée par le compilateur avec ce type de données comme argument et la fonction est exécutée.
Voyons un exemple pour mieux comprendre les modèles de fonctions.
#include using namespace std; template void func_swap(T &arg1, T &arg2) { T temp; temp = arg1; arg1 = arg2; arg2 = temp; } int main() { int num1 = 10, num2 = 20; double d1 = 100.53, d2 = 435.54; char ch1 = 'A', ch2 = 'Z'; cout << 'Original data
'; cout << 'num1 = ' << num1 << ' num2 = ' << num2< num1 = 10 num2 = 20
d1 = 100,53 d2 = 435,54
ch1 = A ch2 = Z Données après échange
num1 = 20 num2 = 10
d1 = 435,54 d2 = 100,53
ch1 = Z ch2 = A
Dans le programme ci-dessus, nous avons défini un modèle de fonction «func_swap» qui permute deux valeurs. La fonction prend deux arguments de référence de type T. Elle échange ensuite les valeurs. Comme les arguments sont des références, les changements que nous apportons aux arguments de la fonction seront reflétés dans la fonction appelante.
Dans la fonction principale, nous définissons des données de type int, double et char. Nous appelons la fonction func_swap avec chaque type de données. Ensuite, nous affichons les données permutées pour chaque type de données.
Cela montre donc que nous n'avons pas besoin d'écrire trois fonctions pour trois types de données. Il suffit d'écrire une seule fonction et d'en faire une fonction modèle pour qu'elle soit indépendante du type de données.
Modèles de cours
Comme dans les modèles de fonction, nous pourrions avoir une exigence d'avoir une classe similaire à tous les autres aspects, mais uniquement des types de données différents.
Dans cette situation, nous pouvons avoir différentes classes pour différents types de données ou une implémentation différente pour différents types de données dans la même classe. Mais faire cela rendra notre code volumineux.
La meilleure solution pour cela est d'utiliser une classe de modèle. La classe de modèle se comporte également de la même manière que les modèles de fonction. Nous devons passer le type de données en tant que paramètre à la classe lors de la création d'objets ou de l'appel de fonctions membres.
La syntaxe générale du modèle de classe est:
template class className{ ….. public: T memVar; T memFunction(T args); };
Dans la définition ci-dessus, T agit comme un espace réservé pour le type de données. Les memVar et memFunction des membres publics utilisent également T comme espace réservé pour les types de données.
Une fois qu'une classe de modèle est définie comme ci-dessus, nous pouvons créer des objets de classe comme suit:
className classObejct1; className classObject2; className classObject3;
Implémentons un exemple de code pour illustrer les modèles de classes:
comment ouvrir un fichier dat
#include using namespace std; template class myclass { T a, b; public: myclass (T first, T second) {a=first; b=second;} T getMaxval (); }; template T myclass::getMaxval () { return (a>b? a : b); } int main () { myclass myobject (100, 75); cout<<'Maximum of 100 and 75 = '< Production:
Maximum de 100 et 75 = 100
Maximum de «A» et «a» = a
Le programme ci-dessus implémente un exemple de modèle de classe. Nous avons la classe de modèle myclass. À l'intérieur, nous avons un constructeur qui initialisera les deux membres a et b de la classe. Il existe une autre fonction membre getMaxval qui est également un modèle de fonction qui renvoie un maximum de a et b.
Dans la fonction principale, nous construisons deux objets, myobject de type integer et mychobject de type character. Ensuite, nous appelons la fonction getMaxval sur chacun de ces objets pour déterminer la valeur maximale.
Notez qu'en dehors des paramètres de type de modèle (paramètres de type T), les fonctions de modèle peuvent également avoir des paramètres ordinaires comme les fonctions normales et également des valeurs de paramètres par défaut.
nom de type Vs. mot-clé de classe
Lors de la déclaration de classe ou de fonction de modèle, nous utilisons l'un des deux mots-clés class ou typename. Ces deux mots sont sémantiquement équivalents et peuvent être utilisés de manière interchangeable.
Mais dans certains cas, nous ne pouvons pas utiliser ces mots comme équivalents. Par exemple, lorsque nous utilisons des types de données dépendants dans des modèles comme «typedef», nous utilisons typename au lieu de class.
De plus, le mot-clé class doit être utilisé lorsque nous devons instancier explicitement un modèle.
Instanciation et spécialisation de modèle
Les modèles sont écrits de manière générique, ce qui signifie qu’il s’agit d’une implémentation générale quel que soit le type de données. Selon le type de données fourni, nous devons générer une classe concrète pour chaque type de données.
Par exemple, si nous avons un algorithme de tri de modèle, nous pouvons générer une classe concrète pour le tri, une autre classe pour le tri, etc. C'est ce qu'on appelle l'instanciation du modèle.
Nous substituons les arguments de modèle (types de données réels) aux paramètres de modèle dans la définition de la classe de modèle.
Par exemple,
template class sort {};
Lorsque nous transmettons le type de données, le compilateur substitue le type de données à «T» afin que l'algorithme de tri devienne tri.
qu'est-ce qu'un fichier .jnlp
Chaque fois que nous utilisons une classe ou une fonction de modèle, une instance est nécessaire lorsque nous transmettons un type de données particulier. Si cette instance n'est pas déjà présente, le compilateur en crée une avec le type de données particulier. Il s'agit de l'instanciation implicite.
Un inconvénient de l'instanciation implicite est que le compilateur génère une classe d'instance uniquement pour les arguments actuellement utilisés. Cela signifie que si nous voulons générer une bibliothèque d'instances avant l'utilisation de ces instances, nous devons opter pour une instanciation explicite.
Un exemple de déclaration de modèle est donné ci-dessous:
template class Array(T)
Peut être explicitement instancié comme:
template class Array
Lorsqu'une classe est instanciée, tous ses membres sont également instanciés.
Spécialisation des modèles
Lors de la programmation à l'aide de modèles, nous pourrions être confrontés à une situation telle que nous pourrions avoir besoin d'une implémentation spéciale pour un type de données particulier. Lorsqu'une telle situation se produit, nous optons pour la spécialisation des modèles.
Dans la spécialisation des modèles, nous implémentons un comportement spécial pour un type de données particulier en dehors de la définition de modèle d'origine pour les autres types de données.
Par exemple, considérez que nous avons une classe de modèle ' myIncrement » qui a un constructeur pour initialiser une valeur et une fonction modèle àIncrément qui incrémente la valeur de 1.
Cette classe particulière fonctionnera parfaitement pour tous les types de données à l'exception de char. Au lieu d'incrémenter la valeur de char, pourquoi ne pas lui donner un comportement spécial et convertir le caractère en majuscules à la place?
Pour ce faire, nous pouvons opter pour une spécialisation de modèle pour le type de données char.
Cette implémentation est illustrée dans l'exemple de code ci-dessous.
#include using namespace std; // class template: template class myIncrement { T value; public: myIncrement (T arg) {value=arg;} T toIncrement () {return ++value;} }; // class template specialization: template class myIncrement { char value; public: myIncrement (char arg) {value=arg;} char uppercase () { if ((value>='a')&&(value<='z')) value+='A'-'a'; return value; } }; int main () { myIncrement myint (7); myIncrement mychar ('s'); myIncrement mydouble(11.0); cout<<'Incremented int value: '<< myint.toIncrement()<< endl; cout<<'Uppercase value: '< Production:
Valeur int incrémentée: 8
Valeur majuscule: S
Valeur double incrémentée: 12
Dans le programme ci-dessus qui démontre la spécialisation des modèles, voyez la manière dont nous avons déclaré un modèle spécialisé pour le type char. Nous déclarons d'abord la classe d'origine, puis nous la «spécialisons» pour le type char. Pour commencer la spécialisation, nous utilisons un «modèle» de déclaration de modèle vide.
Ensuite, après le nom de la classe, nous incluons le type de données. Après ces deux modifications, la classe est écrite pour le type char.
Dans la fonction principale, notez qu'il n'y a aucune différence entre l'instanciation du type char et les autres types. La seule différence est que nous redéfinissons la classe spécialisée.
Notez que nous devons définir tous les membres de la classe spécialisée même s'ils sont exactement les mêmes dans la classe de modèle générique / d'origine. En effet, nous n'avons pas de fonction d'héritage pour les membres du modèle générique au modèle spécialisé.
Modèles Variadic C ++
Jusqu'à présent, nous avons vu des modèles de fonctions qui acceptent un nombre fixe d'arguments. Il existe également des modèles qui acceptent un nombre variable d'arguments. Ces modèles de fonctions sont appelés modèles variadiques. Les modèles Variadic sont l'une des dernières fonctionnalités de C ++ 11.
Les modèles Variadic acceptent un nombre variable d'arguments qui sont de type sécurisé et les arguments sont résolus au moment de la compilation.
Prenons un exemple de programmation complet pour comprendre cela.
#include #include using namespace std; template T summation(T val) { return val; } template T summation(T first, Args... args) { return first + summation(args...); } int main() { long sum = summation(1, 2, 3, 8, 7); cout<<'Sum of long numbers = '<
L'exemple ci-dessus démontre la fonction variadique, «sommation». Comme indiqué ci-dessus, nous avons d'abord besoin d'une fonction de base qui implémente le cas de base. Ensuite, nous implémentons la fonction variadique en haut de cette fonction.
Dans la somme des fonctions variables, «typename… args» est appelé pack de paramètres de modèle alors que «Args… args» est appelé pack de paramètres de fonction .
Après avoir écrit un modèle de fonction qui implémente le cas de base, nous écrivons une fonction variadique qui implémente le cas général. La fonction variadique s'écrit de la même manière que la récursion comme indiqué pour la sommation (args…). Le premier argument est séparé du pack de paramètres de fonction dans le type T (premier).
Avec chaque appel à la sommation, la liste des paramètres se rétrécit d'un argument et finalement la condition de base est atteinte. La sortie affiche la somme des entiers longs et des caractères.
Conclusion
Avec cela, nous concluons ce tutoriel sur les modèles en C ++. Les modèles nous aident à rendre nos programmes génériques, c'est-à-dire indépendants du type.
Lire aussi = >> Tutoriel de modèle de flacon
Les programmes génériques se tiennent toujours au-dessus des autres programmes car nous n'avons pas besoin d'écrire des programmes séparés pour chaque type de données. Ainsi, le développement de programmes génériques de type sécurisé peut être une étape importante vers une programmation efficace.
=> Consultez les didacticiels de formation approfondie sur le C ++ ici.
lecture recommandée
- Tutoriel sur les fonctions principales de Python avec des exemples pratiques
- Fonctionnement des tests pilotés par les données (exemples de QTP et de sélénium)
- Multithreading en C ++ avec des exemples
- Tutoriel Python DateTime avec des exemples
- Exemple de modèle de scénario de test avec des exemples de scénario de test [Télécharger]
- Commande Cut sous Unix avec des exemples
- Exemple de modèle de rapport de test d'acceptation avec des exemples
- Syntaxe des commandes Unix Cat, options avec exemples