Polymorphisme statique
Éviter le surcoût des appels virtuels
Polymorphisme statique est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 2 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.
Deux formes de polymorphisme
C++ prend en charge deux formes de polymorphisme.
- Dynamique : les fonctions virtuelles sont résolues à l’exécution via une table virtuelle
- Statique : les modèles et CRTP sont résolus à la compilation
Le polymorphisme statique échange de la flexibilité contre de la rapidité.
Le coût de virtual
Un appel virtuel nécessite un saut indirect via la table virtuelle. Le compilateur ne peut généralement pas l’intégrer, ce qui empêche de nombreuses optimisations.
#include <iostream>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() = default;
};
struct Square : Shape {
double s;
Square(double x) : s(x) {}
double area() const override { return s * s; }
};
int main() {
Shape* p = new Square(3);
std::cout << p->area() << "\n";
delete p;
return 0;
}Sélection statique avec CRTP
Avec CRTP, la classe de base appelle directement la méthode dérivée au moyen d’une conversion effectuée à la compilation, de sorte que le compilateur peut tout intégrer.
#include <iostream>
template <typename T>
struct Shape {
double area() const { return static_cast<const T*>(this)->area(); }
};
struct Square : Shape<Square> {
double s;
Square(double x) : s(x) {}
double area() const { return s * s; }
};
int main() {
Square sq(3);
std::cout << sq.area() << "\n";
return 0;
}Nommer le relais
Lorsque la classe de base et la classe dérivée définissent toutes deux area, donnez au relais de la classe de base un nom distinct, comme compute, afin qu’il appelle sans ambiguïté l’implémentation de la classe dérivée.
#include <iostream>
template <typename T>
struct Shape {
double compute() const { return static_cast<const T*>(this)->area(); }
};
struct Circle : Shape<Circle> {
double r;
Circle(double x) : r(x) {}
double area() const { return 3.14159 * r * r; }
};
int main() {
Circle c(2);
std::cout << c.compute() << "\n";
return 0;
}Les modèles comme polymorphisme statique
Les modèles de fonction simples constituent également un polymorphisme statique : le même code fonctionne pour tout type qui fournit l’interface requise, selon un typage structurel effectué à la compilation.
#include <iostream>
struct Dog { void speak() const { std::cout << "Woof\n"; } };
struct Cat { void speak() const { std::cout << "Meow\n"; } };
template <typename Animal>
void make_speak(const Animal& a) { a.speak(); }
int main() {
make_speak(Dog{});
make_speak(Cat{});
return 0;
}Lorsque le type est connu
Le polymorphisme statique ne s’applique que lorsque le type concret est connu à la compilation. Si vous devez stocker des objets hétérogènes dans un même conteneur et choisir le comportement à l’exécution, vous avez toujours besoin de fonctions virtuelles.
Pas de conteneurs hétérogènes
Vous ne pouvez pas placer Shape<Square> et Shape<Circle> dans le même std::vector en tant que base commune, car ce sont des types sans lien entre eux. C’est la principale limitation du polymorphisme statique.
Avantage en performance
En intégrant l’appel sélectionné, le compilateur peut propager les constantes et éliminer entièrement la surcharge liée à l’appel de fonction. Dans les boucles serrées portant sur un seul type connu, le polymorphisme statique peut être nettement plus rapide.
#include <iostream>
template <typename T>
struct Op {
int apply(int x) const { return static_cast<const T*>(this)->apply(x); }
};
struct Doubler : Op<Doubler> {
int apply(int x) const { return x * 2; }
};
int main() {
Doubler d;
int sum = 0;
for (int i = 0; i < 5; ++i) sum += d.apply(i);
std::cout << sum << "\n";
return 0;
}Combiner les deux
Vous pouvez utiliser CRTP pour le chemin critique et une fine enveloppe virtuelle lorsque l’effacement de type est nécessaire. Vous obtenez ainsi de la vitesse là où elle compte et de la flexibilité là où elle est requise.
Vérifications statiques de l’interface
Si une classe dérivée oublie d’implémenter la méthode requise, l’erreur apparaît à la compilation, lorsque la fonction relais de la base est instanciée, et non à l’exécution.
#include <iostream>
template <typename T>
struct Greeter {
void greet() const { static_cast<const T*>(this)->hello(); }
};
struct English : Greeter<English> {
void hello() const { std::cout << "Hello\n"; }
};
int main() {
English{}.greet();
return 0;
}Choisir le bon outil
Utilisez le polymorphisme statique lorsque :
- Le type est connu à la compilation
- Les performances sont essentielles
- Vous n’avez pas besoin d’un type de base commun à l’exécution
Sinon, préférez les fonctions virtuelles pour plus de clarté et de flexibilité.
Vérification rapide
Choisissez le principal compromis du polymorphisme statique.
Récapitulatif
Vous avez comparé les polymorphismes statique et dynamique.
- Virtuel = sélection à l’exécution, vtable, conteneurs hétérogènes
- CRTP/modèles = sélection à la compilation, intégrable, plus rapide
- Le statique nécessite que le type soit connu à la compilation
- Choisissez selon vos besoins de flexibilité ou de performance
Questions Fréquemment Posées
La leçon « Polymorphisme statique » est-elle gratuite ?
Oui — le texte complet de « Polymorphisme statique » 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 « Polymorphisme statique » ?
Éviter le surcoût des appels virtuels 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 2 sur 4.
Combien de temps prend la leçon « Polymorphisme statique » ?
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
- L’idiome CRTP
- Polymorphisme statique
- Mixins avec CRTP
- Quand utiliser CRTP