[erledigt] eigenen Klassennamen ermitteln
-
Hi,
ich habe folgende Hierarchie:
Klasse A funktionA / \ Klasse B1 Klasse B1
In funktionA möchte ich Textausgaben senden. Allerdings wüsste ich gern welche Klasse tatsächlich das versendet.
Jemand einen Plan wie man das macht? würd ungern nur dafür ne memberfunktion hinzufügen, die ich dann überschreiben muss.
Da gibts ja dieses RTTI, hab damit aber noch nie was gemacht.
Die Lösung muss auch nicht portabel sein visual c++ 8 muss es verstehen können.Edit:
Klasse A ist abstrakt.
+T
-
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Sowas ist aber nicht wirklich schön und dass du zu faul bist eigentlich auch kein hinreichendes Argument.
-
Gabs da nicht __FUNCTION__?
-
Danke, habs auch grad was gefunden und wollt grad posten, dass es sich erledigt hat..
http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTIstring myname = typeid( *this ).name();
würd ungern nur dafür ne memberfunktion hinzufügen, die ich dann überschreiben muss.
Das hat nix mit faul zu tun. das ist vom design her ungünstig.
-
vlad_tepesch schrieb:
Jemand einen Plan wie man das macht? würd ungern nur dafür ne memberfunktion hinzufügen, die ich dann überschreiben muss.
Dafür sind die aber eigentlich da, die virtuellen Funktionen.
vlad_tepesch schrieb:
Da gibts ja dieses RTTI, hab damit aber noch nie was gemacht.
[...]
Edit:
Klasse A ist abstrakt.mit RTTI/typeid kannst Du in Deiner Situation ein konstante Referenz auf ein std::type_info-Objekt erfragen. Das ist aber nicht sonderlich schlau, das Objekt. Du kannst diese Objekte vergleichen und sie indirekt als Schlüssel eines assoziativen Kontainer benutzen. Die Ergebnisse von std::type_info::name() sind aber nicht standardisiert.
void whoareyou(A* pa) { cout << typeid(*pa).name() << endl; }
Dann gibts ja noch dynamic_cast. Das richtige Werkzeug hängt von Deinem Ziel ab.
Pass auf, dass ein Vergleich der type_info-Objekte nicht die "ist ein"-Beziehung wiederspiegelt. Wenn Du also noch eine Klasse
X
hast, die von B1 erbt undpa
auf ein ObjektX
zeigt, gilt folgendestypeid(*pa) != typeid(B1) // unterschiedliche type_info Objekte dynamic_cast<B1*>(pa) != 0 // Trotzdem erfolgreicher cast
Gruß,
SP
-
das ganze ist nur für eine Log-ausgabe, wo ich sehen will, welche unterklasse gerade diese Informationen ausgibt.
die sache mit der Memberfunktion ist aber die, dass falls man von B1, oder B2 ableitet in klasse Cx nicht gezwungen wird, eine getName-funkion zu überschreiben.
das heißt:
class A{ public: void funkion1(){ cout << "ich bin "<<getClassName(); } virtual string getName()=0; }; class B:public A{ public: virtual string getName(){ return "B"; } }; class C:public B{ // vergessen virtual string getName() zu überschreiben }; A* pa = new C1(); pa->funktion1(); // "Ich bin B" wird ausgegeben
Folgendes ist da angenehmer:
class A{ public: void funkion1(){ cout << "ich bin "<<typeid( *this ).name(); } };
-
Hier würde sich auch der Einsatz von static lohnen.
const char* get_class_name (void) const { static const char* name = typeid (*this).name (); return (name); }
Da man aber zur kompilierzeit seinen Klassennamen bereits kennt, ist es leichter eine get_class_name pure virtual zu machen und den Klassennamen reinzuschreiben, um so auf RTTI komplett zu verzichten.
Eine andere sehr schöne Lösung kann man mit Templates und dem Präprozessor basteln:
#include <stdio.h> template <typename T> struct class_name_traits; #define delcare_class(name) \ struct name; \ template<> struct class_name_traits<name> \ { \ static const char* get_class_name (void) \ { \ return (#name); \ } \ }; \ struct name // Klasse A delcare_class (class_a) { public: int x; }; // Klasse B delcare_class (class_b) { public: int y; }; template<typename T> inline const char* __class_name (const T& obj) { return class_name_traits<T>::get_class_name (); } int main (int argc, char* argv[]) { class_a x; class_b y; printf ("instance of x: %s\n", __class_name (x)); printf ("instance of y: %s\n", __class_name (y)); return 0; }