325 Stimmen

Wie kann ich Reflection zu einer C++-Anwendung hinzufügen?

Ich möchte in der Lage sein, eine C++-Klasse auf ihren Namen, ihren Inhalt (d.h. Mitglieder und ihre Typen) usw. zu untersuchen. Ich spreche hier von nativem C++, nicht von verwaltetem C++, das Reflection hat. Ich weiß, dass C++ mit RTTI einige begrenzte Informationen liefert. Welche zusätzlichen Bibliotheken (oder andere Techniken) könnten diese Informationen liefern?

21 Stimmen

Pech gehabt, ohne Makros und andere Vorverarbeitungen geht es nicht, denn die erforderlichen Metadaten gibt es nicht es sei denn, Sie erstellen sie manuell mit Hilfe von Makro-Vorverarbeitungsmagie.

7 Stimmen

Die Informationen, die Sie von RTTI erhalten können, reichen jedoch nicht aus, um die meisten Dinge zu tun, für die Sie eigentlich eine Reflexion benötigen würden. Sie können zum Beispiel nicht über die Mitgliedsfunktionen einer Klasse iterieren.

15voto

Jérôme Punkte 25617

Ich würde die Verwendung von Qt .

Es gibt sowohl eine Open-Source-Lizenz als auch eine kommerzielle Lizenz.

1 Stimmen

Ich habe mir das angesehen, aber es verwendet Makros, und der Quellcode muss geparst werden, um den Metadatencode zu erzeugen. Diesen zusätzlichen Schritt würde ich gerne vermeiden. Ich würde es vorziehen, eine C++-Bibliothek oder einfache Makros zu verwenden. Trotzdem danke für die Idee.

11 Stimmen

QT oder eine andere Bibliothek, die einen ähnlichen Ansatz implementiert, ist das Beste, was Sie bekommen werden

7 Stimmen

Bezahlen Sie zur Kompilierzeit oder zur Laufzeit - Sie zahlen in jedem Fall!

14voto

KeithB Punkte 15939

Sie müssen sich überlegen, was Sie erreichen wollen und ob RTTI Ihre Anforderungen erfüllt. Ich habe meine eigene Pseudoreflexion für einige sehr spezifische Zwecke implementiert. Zum Beispiel wollte ich einmal flexibel konfigurieren können, was eine Simulation ausgeben sollte. Dazu musste ich den Klassen, die ausgegeben werden sollten, einige Standardtexte hinzufügen:

namespace {
  static bool b2 = Filter::Filterable<const MyObj>::Register("MyObject");
} 

bool MyObj::BuildMap()
{
  Filterable<const OutputDisease>::AddAccess("time", &MyObj::time);
  Filterable<const OutputDisease>::AddAccess("person", &MyObj::id);
  return true;
}

Der erste Aufruf fügt dieses Objekt dem Filtersystem hinzu, das die BuildMap() Methode, um herauszufinden, welche Methoden verfügbar sind.

In der Konfigurationsdatei können Sie dann etwas wie folgt tun:

FILTER-OUTPUT-OBJECT   MyObject
FILTER-OUTPUT-FILENAME file.txt
FILTER-CLAUSE-1        person == 1773
FILTER-CLAUSE-2        time > 2000

Durch eine Art Vorlagenzauber mit boost Dies wird zur Laufzeit (wenn die Konfigurationsdatei gelesen wird) in eine Reihe von Methodenaufrufen übersetzt und ist daher recht effizient. Ich würde nicht empfehlen, dies zu tun, es sei denn, Sie wirklich brauchen, aber, wenn Sie tun, können Sie einige wirklich coole Sachen zu tun.

0 Stimmen

Ich liebe diese Funktionen, die immer true zurückgeben ;) Ich nehme an, dies ist immun gegen Probleme mit der statischen Init-Reihenfolge?

13voto

Ferruccio Punkte 96076

Was wollen Sie mit der Reflexion erreichen?
Sie können den Boost verwenden Typ-Eigenschaften y typeof Bibliotheken als eine begrenzte Form der Reflexion zur Kompilierzeit. Das heißt, Sie können die grundlegenden Eigenschaften eines Typs, der an eine Vorlage übergeben wird, untersuchen und ändern.

13voto

Zack Punkte 131

Es gibt eine weitere neue Bibliothek für Reflexion in C++, die RTTR (Run Time Type Reflection, siehe auch github ).

T

12voto

philant Punkte 32877

EDIT : CAMP wird nicht mehr gepflegt; zwei Abzweigungen sind vorhanden:

  • Man wird auch als CAMP und basiert auf der gleichen API.
  • Überlegen Sie ist eine partielle Neufassung und sollte bevorzugt werden, da sie kein Boost benötigt; sie verwendet C++11.

CAMP ist eine MIT-lizenzierte Bibliothek (früher LGPL), die die Sprache C++ um Reflection erweitert. Sie erfordert keinen speziellen Vorverarbeitungsschritt bei der Kompilierung, aber die Bindung muss manuell vorgenommen werden.

Die aktuelle Tegesoft-Bibliothek verwendet Boost, aber es gibt auch eine Gabelung mit C++11, die benötigt keinen Boost mehr .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X