Modèle C++
Les modèles sont la base de la programmation générique, qui consiste à écrire du code d'une manière indépendante de tout type spécifique.
Un modèle est un plan ou une formule permettant de créer une classe ou une fonction générique. Les conteneurs de bibliothèque, tels que les itérateurs et les algorithmes, sont des exemples de programmation générique utilisant le concept de modèles.
Chaque conteneur a une définition unique, telle que vecteur, et nous pouvons définir de nombreux types différents de vecteurs, tels que vecteur <int> ou vecteur <string>.
Vous pouvez utiliser des modèles pour définir des fonctions et des classes, voyons comment les utiliser.
Modèle de fonction
La forme générale d'une définition de fonction de modèle est la suivante :
template <class type> ret-type func-name(parameter list) { // 函数的主体 }
Ici, type est un nom d'espace réservé pour le type de données utilisé par la fonction. Ce nom peut être utilisé dans les définitions de fonctions.
Ce qui suit est un exemple de modèle de fonction qui renvoie la valeur maximale de deux nombres :
#include <iostream> #include <string> using namespace std; template <typename T> inline T const& Max (T const& a, T const& b) { return a < b ? b:a; } int main () { int i = 39; int j = 20; cout << "Max(i, j): " << Max(i, j) << endl; double f1 = 13.5; double f2 = 20.7; cout << "Max(f1, f2): " << Max(f1, f2) << endl; string s1 = "Hello"; string s2 = "World"; cout << "Max(s1, s2): " << Max(s1, s2) << endl; return 0; }
Lorsque le code ci-dessus est compilé et exécuté, il produira les résultats suivants :
Max(i, j): 39 Max(f1, f2): 20.7 Max(s1, s2): World
Modèle de classe
Tout comme nous définissons des modèles de fonctions, nous pouvons également définir des modèles de classe. La forme générale d'une déclaration de classe générique est la suivante :
template <class type> class class-name { . . . }
Ici, type est un nom de type d'espace réservé qui peut être spécifié lorsque la classe est instanciée. Vous pouvez définir plusieurs types de données génériques à l'aide d'une liste séparée par des virgules.
L'exemple suivant définit la classe Stack<> et implémente des méthodes génériques pour pousser et placer des éléments sur la pile :
#include <iostream> #include <vector> #include <cstdlib> #include <string> #include <stdexcept> using namespace std; template <class T> class Stack { private: vector<T> elems; // 元素 public: void push(T const&); // 入栈 void pop(); // 出栈 T top() const; // 返回栈顶元素 bool empty() const{ // 如果为空则返回真。 return elems.empty(); } }; template <class T> void Stack<T>::push (T const& elem) { // 追加传入元素的副本 elems.push_back(elem); } template <class T> void Stack<T>::pop () { if (elems.empty()) { throw out_of_range("Stack<>::pop(): empty stack"); } // 删除最后一个元素 elems.pop_back(); } template <class T> T Stack<T>::top () const { if (elems.empty()) { throw out_of_range("Stack<>::top(): empty stack"); } // 返回最后一个元素的副本 return elems.back(); } int main() { try { Stack<int> intStack; // int 类型的栈 Stack<string> stringStack; // string 类型的栈 // 操作 int 类型的栈 intStack.push(7); cout << intStack.top() <<endl; // 操作 string 类型的栈 stringStack.push("hello"); cout << stringStack.top() << std::endl; stringStack.pop(); stringStack.pop(); } catch (exception const& ex) { cerr << "Exception: " << ex.what() <<endl; return -1; } }
Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :
7 hello Exception: Stack<>::pop(): empty stack