Statischer Polymorphismus
Overhead virtueller Aufrufe vermeiden
Statischer Polymorphismus ist eine kostenlose C++ Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C++ Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Zwei Arten von Polymorphie
C++ unterstützt zwei Formen der Polymorphie.
- Dynamisch: Virtuelle Funktionen werden zur Laufzeit über eine vtable aufgelöst
- Statisch: Templates und CRTP werden zur Compilezeit aufgelöst
Statische Polymorphie tauscht Flexibilität gegen Geschwindigkeit.
Die Kosten von virtual
Ein virtueller Aufruf erfordert einen indirekten Sprung über die vtable. Der Compiler kann ihn normalerweise nicht inline expandieren, wodurch viele Optimierungen verhindert werden.
#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;
}Statische Auflösung mit CRTP
Bei CRTP ruft die Basisklasse die Methode der abgeleiteten Klasse direkt über eine zur Compilezeit aufgelöste Umwandlung auf, sodass der Compiler alles inline expandieren kann.
#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;
}Benennung von Weiterleitungsfunktionen
Wenn die Basis- und die abgeleitete Klasse beide area definieren, geben Sie der Weiterleitungsfunktion der Basisklasse einen eigenen Namen wie compute, damit sie eindeutig die Implementierung der abgeleiteten Klasse aufruft.
#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;
}Templates als statische Polymorphie
Einfache Funktionstemplates sind ebenfalls statische Polymorphie: Derselbe Code funktioniert für jeden Typ, der die erforderliche Schnittstelle bereitstellt (Duck-Typing zur Compilezeit).
#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;
}Wenn der Typ bekannt ist
Statischer Polymorphismus funktioniert nur, wenn der konkrete Typ zur Compile-Zeit bekannt ist. Wenn Sie heterogene Objekte in einem Container speichern und das Verhalten zur Laufzeit auswählen müssen, benötigen Sie weiterhin virtuelle Funktionen.
Keine heterogenen Container
Sie können Shape<Square> und Shape<Circle> nicht als gemeinsame Basisklasse in denselben std::vector aufnehmen, da es sich um voneinander unabhängige Typen handelt. Das ist die zentrale Einschränkung des statischen Polymorphismus.
Leistungsvorteil
Durch das Inlining des Dispatch-Aufrufs kann der Compiler Konstanten zusammenfassen und den Overhead von Funktionsaufrufen vollständig eliminieren. In engen Schleifen über einen einzelnen bekannten Typ kann statischer Polymorphismus deutlich schneller sein.
#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;
}Beides kombinieren
Sie können CRTP für den Hot Path und einen dünnen virtuellen Wrapper verwenden, wenn Type Erasure erforderlich ist. So erhalten Sie dort Geschwindigkeit, wo sie zählt, und dort Flexibilität, wo sie erforderlich ist.
Statische Schnittstellenprüfungen
Vergisst eine abgeleitete Klasse, die erforderliche Methode zu implementieren, tritt der Fehler zur Compile-Zeit auf, wenn der Base-Forwarder instanziiert wird, nicht zur Laufzeit.
#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;
}Das richtige Werkzeug wählen
Verwenden Sie statischen Polymorphismus, wenn:
- Der Typ zur Compile-Zeit bekannt ist
- Die Performance kritisch ist
- Sie keinen gemeinsamen Laufzeit-Basistyp benötigen
Andernfalls bevorzugen Sie virtuelle Funktionen wegen ihrer Klarheit und Flexibilität.
Kurzer Test
Bestimmen Sie den entscheidenden Zielkonflikt des statischen Polymorphismus.
Zusammenfassung
Sie haben statischen und dynamischen Polymorphismus verglichen.
- Virtual = Dispatch zur Laufzeit, VTable, heterogene Container
- CRTP/Templates = Dispatch zur Compile-Zeit, inline-fähig, schneller
- Statischer Polymorphismus setzt voraus, dass der Typ zur Compile-Zeit bekannt ist
- Wählen Sie je nach Bedarf zwischen Flexibilität und Performance
Häufig gestellte Fragen
Ist die Lektion „Statischer Polymorphismus“ kostenlos?
Ja — der vollständige Text von „Statischer Polymorphismus“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C++ Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Statischer Polymorphismus“?
Overhead virtueller Aufrufe vermeiden Du übst C++ Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C++ Academy zu starten?
Keine Vorkenntnisse erforderlich. C++ Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Statischer Polymorphismus“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C++ Academy-Lektion Code schreiben und ausführen?
Ja. Jede C++ Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Das CRTP-Idiom
- Statischer Polymorphismus
- Mixins mit CRTP
- Wann Sie CRTP verwenden sollten