C++ Academy · Leçon

Mixins avec CRTP

Composer un comportement lors de la compilation

Leçon 3 sur 413 étapes

Mixins avec CRTP est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.

Qu’est-ce qu’un module de composition ?

Un module de composition est une petite unité de comportement réutilisable que vous composez dans une classe. Avec CRTP, les modules de composition ajoutent des fonctionnalités à la compilation tout en appelant la classe hôte.

Un module de composition simple

Ce module de composition ajoute une méthode print_twice qui s’appuie sur la présence de value() dans la classe hôte.

#include <iostream>

template <typename T>
struct PrintTwice {
    void print_twice() const {
        auto v = static_cast<const T*>(this)->value();
        std::cout << v << " " << v << "\n";
    }
};

struct Box : PrintTwice<Box> {
    int value() const { return 7; }
};

int main() {
    Box{}.print_twice();
    return 0;
}

Composer plusieurs modules

Vous pouvez hériter simultanément de plusieurs modules de composition CRTP et superposer des comportements indépendants dans une seule classe.

#include <iostream>

template <typename T>
struct Loggable {
    void log() const { std::cout << "log: " << static_cast<const T*>(this)->id() << "\n"; }
};

template <typename T>
struct Resettable {
    void reset() { static_cast<T*>(this)->set(0); }
};

struct Device : Loggable<Device>, Resettable<Device> {
    int v = 5;
    int id() const { return v; }
    void set(int x) { v = x; }
};

int main() {
    Device d;
    d.log();
    d.reset();
    d.log();
    return 0;
}

Les modules de composition ajoutent aussi un état

Un module de composition peut contenir ses propres membres de données, qui deviennent alors partie intégrante de la disposition mémoire de l’objet composé.

#include <iostream>

template <typename T>
struct Tagged {
    int tag = 0;
    void set_tag(int t) { tag = t; }
    int get_tag() const { return tag; }
};

struct Item : Tagged<Item> {
    const char* name = "item";
};

int main() {
    Item it;
    it.set_tag(42);
    std::cout << it.name << " " << it.get_tag() << "\n";
    return 0;
}

Module de composition ou héritage classique

Un module de composition CRTP se distingue de l’héritage ordinaire, car la base peut appeler la classe dérivée en redescendant dans la hiérarchie. Les classes de base ordinaires ne peuvent pas appeler des méthodes qui existent uniquement dans le type dérivé sans fonctions virtuelles.

Conception fondée sur des politiques

Les modules de composition permettent une conception fondée sur des politiques : les comportements sont sélectionnés à la compilation en choisissant les modules dont hériter, de manière similaire à la politique d’allocation acceptée par std::vector.

Ordre et disposition mémoire

Lorsque vous empilez des modules de composition, l’ordre des bases influe sur l’ordre de construction et sur la disposition mémoire de l’objet. Gardez les modules indépendants afin que l’ordre n’ait aucune incidence sur la correction du programme.

  • Construisez dans l’ordre de déclaration des bases
  • Évitez les modules de composition qui dépendent les uns des autres

Ajouter un module d’égalité

Ce module de composition génère ici operator!= à partir de l’égalité de la classe hôte.

#include <iostream>

template <typename T>
struct EqualityMixin {
    friend bool operator!=(const T& a, const T& b) { return !(a == b); }
};

struct P : EqualityMixin<P> {
    int x;
    P(int v) : x(v) {}
    friend bool operator==(const P& a, const P& b) { return a.x == b.x; }
};

int main() {
    std::cout << (P(1) != P(2)) << "\n";
    return 0;
}

Modules de composition conditionnels

Vous pouvez inclure un module de composition uniquement lorsqu’une condition est satisfaite, en combinant l’héritage avec std::conditional pour choisir entre un module réel et un module vide.

Optimisation des bases vides

Les modules de composition qui ne contiennent aucun membre de données bénéficient de l’optimisation des bases vides : le compilateur ne leur alloue aucun octet supplémentaire. Empiler de nombreux modules de composition sans état ne coûte donc rien en taille.

#include <iostream>

template <typename T>
struct A {};
template <typename T>
struct B {};

struct C : A<C>, B<C> {
    int x;
};

int main() {
    std::cout << (sizeof(C) == sizeof(int)) << "\n";
    return 0;
}

Quand utiliser les modules de composition

Les modules de composition sont particulièrement utiles lorsque de nombreuses classes ont besoin des mêmes comportements orthogonaux (journalisation, comptage, comparaison). Ils permettent de définir chaque comportement à un seul endroit et de les composer sans coût à l’exécution.

Vérification rapide

Vérifiez votre compréhension des modules de composition CRTP.

Récapitulatif

Vous avez appris à construire des modules de composition avec CRTP.

  • Les modules de composition associent des comportements orthogonaux à la compilation
  • Ils peuvent appeler la classe hôte en redescendant dans la hiérarchie et conserver un état
  • Les modules de composition sans état ne coûtent rien grâce à l’optimisation des bases vides
  • Ils conviennent parfaitement aux politiques de journalisation, de comparaison et de comptage
Gratuit pour commencer

Apprends C++ avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
51
Leçons
203

Questions Fréquemment Posées

La leçon « Mixins avec CRTP » est-elle gratuite ?

Oui — le texte complet de « Mixins avec CRTP » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Mixins avec CRTP » ?

Composer un comportement lors de la compilation Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C++ Academy ?

Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Mixins avec CRTP » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?

Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. L’idiome CRTP
  2. Polymorphisme statique
  3. Mixins avec CRTP
  4. Quand utiliser CRTP
← Retour à C++ Academy