Modèles en C ++

C ++ est un exemple d'un langage de programmation fortement typé. Il est cette-ness tapé fort qui permet aux fonctions d'être surchargés, comme le montre l'extrait de code suivant:

Sommaire

Note void (étudiants) de grade -void (Land) fn -void (étudiants s) {année (s) -}

C ++ n'a pas de problèmes de compréhension que l'appel à Note (s) doivent être adressées à la fonction année (étudiants).

Forces de typage fort méthodes pour être surchargés qui apparaissent même au niveau C ++, mais sont très différents dans leur mise en œuvre comme dans l'exemple suivant:

int compare (int l, int r) {return (l> r)? 1: (l lt; r)? -1: 0-} int comparer (Double L, double r) {return (l> r)? 1: (l lt; r)? -10-}

Ce comparer () Renvoie 1 si la gauche; argument main est supérieure à la droite; la main, -1 si la gauche; argument main est moins que le droit; la main, et un 0 si elles sont égales. En dépit de la similitude du code source, le code machine généré par ces deux fonctions est très différent en raison de différences dans la manière dont int est mis en oeuvre par rapport à double au niveau de la machine.

Le préprocesseur propose une façon d'éviter de telles implémentations redondants:

#define COMPARER (L, R) (((l)> (r)) 1:? ((l) lt; (r)) -1: 0)

Cependant, cette souffre d'un certain nombre de limitations graves - pas le moindre, est la nécessité pour la fonction pour adapter en une seule expression (en effet, sur une seule ligne). En outre, des erreurs dans une macro de préprocesseur peuvent conduire à des problèmes qui sont difficiles à déboguer.

Modèles de fonction

La fonction de modèle en C ++ permet au programmeur de conserver les avantages de typage fort et d'éviter les limitations du préprocesseur en utilisant un espace réservé pour le type. Les définit suivants comparer () pour certains classe non spécifiée T à être nommé plus tard:

modèle  T comparer (T l, T r) {return (l> r)? 1: (l lt; r)? -10-}

Une telle définition est connue en tant que modèle de fonction. Ce modèle de fonction - dont le nom complet est comparer(T, T) - peut être converti en une fonction réelle en fournissant T:

matrice double comparer(double, double) -

Vous pouvez également permettre à C ++ pour trouver et instancier la classe T pour vous, soit en fournissant une déclaration partielle ou en utilisant la fonction comme le montre l'exemple de code extrait suivant:

matrice double comparer (doubles, doubles) -int main () {cout lt; lt; comparer (0, 0) lt; lt; "" Lt; lt; comparer (1.0, 2.0) lt; lt; endl-retour 0-}

Ici, la fonction comparer (doubles, doubles) est créé par la déclaration initiale, même sans le supplément après le nom de la fonction. La fonction comparer (int, int) est créé quand il est utilisé dans la déclaration comparer (0, 0).

Modèles de classe

La fonction C de modèle permet à des classes à définir l'utilisation des types qui sont spécifiés plus tard. Cela résout un certain nombre de problèmes d'une manière de type sécurisé. Un problème, bien que loin d'être le seul problème, est que de conteneurs génériques. (UN récipient est une classe qui contient des objets d'une autre classe.)

Dans les premiers jours de C ++, la seule façon de créer une classe de conteneur générique était de compter sur le générique vide pointeur (le pointeur de la classe void *). Tout comme le #define «fonction» mentionné plus haut, cette approche efficacement évité mécanisme de typage fort de C ++ avec des déclarations comme celles-ci:

classe Container {public: void add (void *) - void * get () - // ... autres membres ...} - Classe storeStudent conteneur vide (étudiants s) {conteneur.add ((void *) s) -} étudiants * getStudent () {return (Student *) container.get () -}

Les modèles de C permettent au programmeur de définir un modèle de classe dans laquelle un ou plusieurs types ne sont pas spécifiés jusqu'à ce que la classe est utilisée:

modèle  classe Container {public: vente vide (T * p) -T * get () -} -

En pratique, le modèle de classe doit d'abord être converti en une véritable classe en fournissant un type pour T. Il peut alors être utilisé en toute sécurité de type:

Récipient conteneur-s étudiant-container.put (s) -Student * PS = container.get () -

Il n'y a pas besoin de définir votre propre conteneur de classe le Standard Template Library fournit un certain nombre de ces classes. Par exemple, l'extrait de code suivant crée une liste chaînée de pointeurs Étudiant objets et ajoute un à la fin de la liste:

// Doit #inclure  au début de ModuleList sList-Étudiant * PS = new Étudiant () - sList.push_back (s) -

Beaucoup de classes que vous utilisez au quotidien sont, en fait, instanciations de modèles de classe. L'exemple le plus fréquent est celui où istream et ostream sont utilisés pour l'entrée et la sortie standard.

Itérateurs

Bien qu'ils ne sont pas directement partie de la fonction de modèle, itérateurs fournir un moyen standard pour accéder aux différents types de conteneurs disponibles dans la bibliothèque de modèles standard. Tous les conteneurs fournissent une méthode qui retourne un itérateur au début du conteneur et un moyen de vérifier si l'itérateur est à la fin du récipient (ce qui inclut les conteneurs non ordonnées pour qui «début» et «fin» est un concept aléatoire). L'itérateur lui-même fournit au moins deux méthodes: l'une pour retourner l'objet courant et un pour éviter l'itérateur à l'objet suivant.

Les itération de code suivants à travers une collection de pointeurs Étudiant objets. Ce même code fonctionne quel que soit l'un des nombreux types de conteneurs que vous choisissez d'utiliser:

// DisplayAllStudents - parcourir une liste des // étudiants- invoquer la toString () // méthode sur displayAllStudents eachvoid (liste sList) {for (iter auto = sList.begin (!) - iter = sList.end () - iter ++) {Etudiant * PS = * iter-cout lt; lt; PS-> toString () lt; lt; endl-}}

(Cet exemple suppose que la classe Étudiant un procédé comprend toString () qui renvoie une représentation de caractères d'un étudiant.)

Cette fonction utilise le commencer() Procédé pour retourner un itérateur qui pointe vers le premier élément de récipient. Les itération de fonction à travers le récipient jusqu'à ce que les points de itérateur fin() qui se réfère à l'organe après le dernier membre dans le conteneur. L'opérateur d'incrémentation déplace l'itérateur à l'élément suivant dans le récipient tandis que l'opérateur * renvoie l'objet pointé par l'itérateur.

La auto mot-clé dit déclarer iter pour être du type renvoyé par sList.begin (). Ceci est une extension de C ++ ajouté par la norme 2011. Sans auto, Je l'aurais déclaré iter être de type liste ::const_iterator.