Syntaxe des modèles de classe
Les modèles de classe permettent de créer des structures génériques où les types des membres sont paramétrables.
template<typename T>
class NomClasse {
// Définition
};
Exemple pratique
#include <string>
template<typename NomT, typename AgeT>
class Individu {
public:
Individu(NomT nom, AgeT age) : m_nom(nom), m_age(age) {}
void afficher() const {
std::cout << "Nom: " << m_nom << " Âge: " << m_age << std::endl;
}
NomT m_nom;
AgeT m_age;
};
void demo() {
Individu<std::string, int> sujet("Zelda", 120);
sujet.afficher();
}
Différences avec les modèles de fonction
- Aucune déduction auotmatique de type
- Paramètres par défaut autorisés
template<typename NomT, typename AgeT = int>
class Individu { /*...*/ };
void exemple() {
// Individu sujet("Ezio", 35); // Erreur
Individu<std::string> sujet("Altair", 85); // Âge par défaut (int)
}
Création différée des méthodes
Les méthodes des modèles de clasce sont instanciées uniquement lors de leur utilisation.
class TypeA {
public:
void operationA() const { /*...*/ }
};
template<typename T>
class Conteneur {
public:
T element;
void utiliser() { element.operationA(); } // Instanciée si appelée
};
void test() {
Conteneur<TypeA> c;
c.utiliser(); // Compile
// c.element.operationB(); // Échec si operationB n'existe pas
}
Objets comme paramètres de fonction
Trois méthodes pour passer des objets template :
// 1. Type explicite
void afficher(Individu<std::string, int>& sujet) {
sujet.afficher();
}
// 2. Paramètres template
template<typename N, typename A>
void afficherTemplate(Individu<N, A>& sujet) {
sujet.afficher();
}
// 3. Classe template
template<typename C>
void afficherGenerique(C& sujet) {
sujet.afficher();
}
Héritage avec modèles
Les classes dérivées doivent spécifier les types des bases template.
template<typename T>
class Base { T membre; };
class Descendant : public Base<int> {}; // Type spécifié
template<typename U, typename V>
class DescendantTemplate : public Base<V> {}; // Type paramétrable
Implémentation hors-classe
Les méthodes définies hors classe nécessitent une syntaxe spécifique :
template<typename N, typename A>
class Individu {
public:
Individu(N nom, A age);
};
template<typename N, typename A>
Individu<N, A>::Individu(N nom, A age) : m_nom(nom), m_age(age) {}
Gestion des fichires
Solution recommandée : utiliser des fichiers .hpp combinant déclaration et définition.
Amitié (friend) avec templates
Implémentation interne recommandée pour les fonctions amies :
template<typename N, typename A>
class Individu {
friend void afficher(const Individu<N, A>& sujet) {
std::cout << sujet.m_nom;
}
};