Objekte unterscheiden: Funktion ist_ein(...) implementieren
-
Hallo,
ich hätte für mein Projekt gerne folgende Funktionalität, die ich aus einem anderen Projekt kenne, aber nicht mehr genau weiss, wie sie realisiert wurde

Ich hätte gerne in jeder Klasse eine öffentliche Funktion
virtual bool ist_ein(const CKlassenBeschreiber&)die mir "wahr" liefert, wenn ein Objekt der Klasse entspricht.
Nehmen wir an, ich hätte die Klassen "Fahrzeug", davon abgeleitet "Auto".
Nun habe ich einen Zeiger auf ein Auto (wobei ich nicht weiss, dass es sich um ein Auto handelt), dann soll die Funktion ist_ein(AUTO) true liefern und der Aufruf ist_ein(FAHRZEUG) ebenfalls.In der Implementierung, die ich mal gesehen habe, hatte jede Klasse ein Objekt
extern const CKlassenBeschreiber AUTO //bzw. FAHRZEUGLeider fehlt mir der entscheidende Ansatz.
Kann mir jemand helfen? Seh ich vielleicht den Wald vor lauter Bäumen nicht oder ist es doch nicht so trivial? Was ist mit typeid etc.? Hilft mir ja nicht, wenn ich auch Basisklassen erkennen will oder?
Vielen Dank.
-
Hallo
dazu kannst du dynamic_cast<> benutzen.
Fahrzeug *MeinFahrzeug; ... Auto *MeinAuto = dynamic_cast<Auto *>(MeinFahrzeug); if (MeinAuto) { // MeinnFahrzeug war vom Typ Auto }Dazu must du in deinem Compiler aber die RTTI aktivieren.
Allerdings ist es besser, wenn du durch eine geeignete Basisklasse (mit virtuellen Methoden) nicht wissen must, von welchem Typ die Instanz letztendich ist.
bis bald
akari
-
Muß man für einen dynamic_cast wirklich RTTI aktivieren?
-
Hallo
Überleg dir mal, was RTTI bedeutet und was den der dynamic_cast überprüfen soll.
bis bald
akari
-
OK, aber
Auto* mercedes = new Auto();Dann funktioniert
if(mercedes->ist_ein(FAHRZEUG)) {...}aber nicht oder?
D.h. ich kann keine Rückschlüsse auf die Basisklasse ziehen.
-
Hallo
nein, so geht das in C++ nicht. Wie so etwas gemacht werden kann, hab ich dir doch schon geschrieben.
bis bald
akari
-
Hallo
nein, so geht das in C++ nicht. Wie so etwas gemacht werden kann, hab ich dir doch schon geschrieben.
bis bald
akariDas ist nicht zufriedenstellend! Ich will doch nicht casten

Also hier mein einfacher Vorschlag:
class CKlassenBeschr { private: const int fid; static int sid; public: CKlassenBeschr(); virtual ~CKlassenBeschr(); const int gib_id() const { return fid; }; }; const bool operator==(const CKlassenBeschr& akbl, const CKlassenBeschr& akbr);#include "klassenbeschr.h" int CKlassenBeschr::sid = 0; CKlassenBeschr::CKlassenBeschr():fid(sid) { sid++; } CKlassenBeschr::~CKlassenBeschr() { } const bool operator==(const CKlassenBeschr& akbl, const CKlassenBeschr& akbr) { return akbl.gib_id()==akbr.gib_id()?true:false; };const CKlassenBeschr C_KLASSE; class CKlasse:public CKlasse2 { private: public: CKlasse(); const bool ist_ein(const CKlassenBeschr & akb) const { return (akb==C_KLASSE || CKlasse2::ist_ein(akb))?true:false; } };
-
Ja, das ist auch eine Möglichkeit - nur solltest du die CKlassenBeschr eventuell etwas anpassen:
* virtueller Destruktor ist unnötig (oder willst du etwas davno ableiten?)
* ob Kopien nötig sind, weiß ich auf Anhieb nicht - eventuell könntest du Copy-Ctor und op= privat deklarieren
* staische globale Objekte werden in zufälliger Reihenfolge initialisiert - also bekommst du vermutlich Probleme, wenn eins deiner Class-ID Objekte vor CKlassenBeschr::sid angelegt wird
-
Noch ein Tipp wegen den statischen sachen...
Du kannst es auch so machen;class Klasse { public: static char dummy; const int gib_id() { return reinterpret_cast<int>(&dummy); } }Nimmt man die Adresse hat man zwei Vorteile:
- Sie ist eindeutig
- Sie ist auf jeden Fall initialisiertBei Deiner Idee könnte man doch zum Beispiel sagen jeder "BasisTyp" bekommt eine Primzahl als Typ-Id. Jeder abgeleitete Typ hat die Typ_id: BasisTypId * die BasisPrimzahl. Damit könnte man ja sogar Mehrfachableitungen hinkriegen. Oder? (Nicht für riesen Projekte geeignet)
-
Danke Leute, prima Ideen
!!!
-
Schon klar, dass RTTI Informationen zur Laufzeit bereitstellt
Aber stehen in der vtable nicht eh die typids und die werden dann verglichen?
Also möchte ich die Frage nochmal in den Raum stellen
Muß man für einen dynamic_cast wirklich RTTI aktivieren?