Modèles de Classe en C++

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

  1. Aucune déduction auotmatique de type
  2. 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;
    }
};

Étiquettes: C++ Templates Programmation Générique classes génériques Paramètres Template Méta-programmation

Publié le 13 juillet à 17h49