Reflexion und Introspection in C++: Wie man Code dazu bringt, sich selbst zu sehen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Was sind Reflexion und Introspection in C++ und wozu braucht man sie?

\n\n

Stellen Sie sich vor, Sie schreiben eine komplexe Spiel-Engine oder ein Framework zur Datenverarbeitung. Irgendwann müssen Sie verstehen: „Was ist das überhaupt für ein Objekt? Welche Methoden hat es? Hat es ein Feld name?“

\n\n

In Sprachen wie Python oder Java erledigt man das mit einer Zeile – dort gibt es vollwertige Reflexion (die Fähigkeit eines Programms, seine eigene Struktur zur Laufzeit zu untersuchen und zu verändern). In C++ ist das jedoch komplizierter. C++ ist eine stark statisch typisierte Sprache und bietet „von Haus aus“ kaum Reflexion. Es gibt jedoch Introspection – die eingeschränkte Fähigkeit, Informationen über Typen zur Laufzeit zu erhalten.

\n\n

In diesem Artikel behandeln wir:

\n
    \n
  • Worin sich Reflexion und Introspection unterscheiden;
  • \n
  • Wie RTTI (Run-Time Type Information) funktioniert;
  • \n
  • Wie man typeid und dynamic_cast verwendet;
  • \n
  • Wie man Reflexion mit Templates und Makros emuliert;
  • \n
  • Moderne Alternativen (C++20/23) und Bibliotheken.
  • \n
\n\n

Bereit für einen Blick in den „Spiegelsaal“ von C++? Los geht's!

\n\n

Introspection vs. Reflexion: Was ist der Unterschied?

\n\n

Bevor wir Code schreiben, lassen Sie uns die Begriffe klarstellen.

\n\n
    \n
  • Introspection – die Fähigkeit eines Programms, „sich selbst zu betrachten“ und Informationen über Typen zu erhalten, aber nicht die Programmstruktur zu verändern. Beispiel: „Den Klassennamen eines Objekts herausfinden“. Das ist in C++ über RTTI möglich.
  • \n
  • Reflexion – das ist Introspection plus die Fähigkeit, Objekte dynamisch zu erstellen, Methoden aufzurufen und Felder zu verändern. Das gibt es im C++-Standard (noch) nicht.
  • \n
\n\n

In C++ verwenden wir den Begriff „Reflexion“ oft als Ziel und „Introspection“ als das verfügbare Werkzeug. Aber keine Sorge: Auch mit den eingeschränkten Mitteln kann man tolle Dinge tun.

\n\n

RTTI (Run-Time Type Information) – die Grundlage der Introspection in C++

\n\n

RTTI ist ein Mechanismus, der es erlaubt, den Typ eines Objekts zur Laufzeit zu bestimmen. Er ist standardmäßig aktiviert (obwohl er in einigen eingebetteten Systemen mit dem Flag -fno-rtti deaktiviert wird).

\n\n

Die Hauptakteure von RTTI:

\n
    \n
  • typeid – ein Operator, der std::type_info zurückgibt;
  • \n
  • dynamic_cast – eine sichere Typumwandlung für polymorphe Typen.
  • \n
\n\n

Beispiel 1: Verwendung von typeid

\n\n
#include <iostream>\n#include <typeinfo>\n\nclass Base { virtual void foo() {} };\nclass Derived : public Base {};\n\nint main() {\n    Base* b = new Derived();\n    std::cout << "Typ des Objekts: " << typeid(*b).name() << std::endl;\n    delete b;\n    return 0;\n}
\n\n

Ausgabe (abhängig vom Compiler): class Derived oder 7Derived (gemangelter Name).

\n\n

Beachten Sie: typeid funktioniert nur mit polymorphen Klassen (die mindestens eine virtuelle Methode haben). Wenn Sie virtual entfernen, erhalten Sie den Typ des Zeigers, nicht das tatsächliche Objekt.

\n\n

Beispiel 2: dynamic_cast – sichere Typumwandlung

\n\n
#include <iostream>\n\nclass Animal { public: virtual ~Animal() = default; };\nclass Dog : public Animal { public: void bark() { std::cout << "Woof!\\n"; } };\nclass Cat : public Animal { public: void meow() { std::cout << "Meow!\\n"; } };\n\nvoid makeSound(Animal* a) {\n    if (Dog* dog = dynamic_cast<Dog*>(a)) {\n        dog->bark();\n    } else if (Cat* cat = dynamic_cast<Cat*>(a)) {\n        cat->meow();\n    } else {\n        std::cout << "Unbekanntes Tier\\n";\n    }\n}\n\nint main() {\n    Animal* pets[] = { new Dog(), new Cat(), new Animal() };\n    for (auto p : pets) makeSound(p);\n    // Nicht vergessen zu löschen!\n    for (auto p : pets) delete p;\n    return 0;\n}
\n\n

Dies ist ein klassisches Beispiel für Introspection: Wir wissen nicht, welches konkrete Objekt ankommt, aber m

Blogs

Buchempfehlungen