Type, GetType
-
Hallo,
aus C# kenne ich die Reflektions Funktionalität, also sprich die GetType Funktion. Dabei gibt ein Objekt zurück, welchen Typs es ist.
Gibt es etwas vergleichbares in C++?
lg Neulinger
-
http://www.cplusplus.com/reference/std/typeinfo/type_info/
Meiner Meinung nach sollte das allerdings nicht allzu oft zum Einsatz kommen. Wo benötigst Du das denn?
-
Eisflamme schrieb:
Meiner Meinung nach sollte das allerdings nicht allzu oft zum Einsatz kommen.
Würde eher sagen selten bis garnicht. Für Debugzwecke kann mans ausgeben, viel mehr kann man damit nicht anfangen, zumal die Ausgabe von type_info::name() nicht genauer spezifiziert ist.
-
Was genau spricht dagegen, dass man es generell ablehnt? Ich schätze die Information wird in der Klasse gehalten, dadurch wird sie etwas größer, aber sonst? Soweit ich mich erinnere funktioniert RTTI auch nur mit virtuellen Klassen, somit übergebe ich also dem Compiler nicht die volle Kontrolle über die Information.
-
pumuckl schrieb:
Für Debugzwecke kann mans ausgeben, viel mehr kann man damit nicht anfangen, zumal die Ausgabe von type_info::name() nicht genauer spezifiziert ist.
type_info::name()kann man nicht brauchen, das stimmt. Aber das bedeutet nicht, dasstype_infoselbst auch nutzlos ist.Wenn man Dinge wie Dynamic-Dispatch implementieren will, ist
type_infosehr praktisch. Oder als Bedingung inassert. Benötigt man zwar nicht andauernd, aber das kann man von vielen Sprachmitteln behaupten. Wobei man ein paar echt nie braucht...
hav a break schrieb:
Was genau spricht dagegen, dass man es generell ablehnt?
Nicht generell. Aber es gibt eben Leute, die missbrauchen
typeidfür explizite Typunterscheidungen, obwohl virtuelle Funktionen sinnvoller wären.
-
Ich muss "Factories" benutzen, da erst zur Laufzeit bekannt wird, aus welchen Klassen Objekte gebildet werden... An der Stelle möchte ich dann Listen und Maps erstellen, bei denen ich die Typen hinterlege.
Ich kann momentan noch nicht nachvollziehen, was für einen Datentyp das typeid zurückgibt?!
type_info test = typeid(int); //Compiler sagt: Kein Zugriff auf private Member@Nexus: Was versteht man unter "explizite Typunterscheidungen". Kannst du ein Beispiel nennen?
-
Neulinger schrieb:
Ich muss "Factories" benutzen, da erst zur Laufzeit bekannt wird, aus welchen Klassen Objekte gebildet werden... An der Stelle möchte ich dann Listen und Maps erstellen, bei denen ich die Typen hinterlege.
Du möchtest die type_info als Schlüsselwort in deiner abstrakten Fabrik benutzen? Ich kann mir grad nicht vorstellen, wieso man das möchte. Kannst ja mal ein Beispiel geben wie deine Fabnrik funktionieren soll.
Schau dir mal diese Factory an:
http://www.drdobbs.com/184403786
Die Typen registrieren sich dort selber bei der Fabrik. Man könnte dort auch type_info als Schlüssel benutzen, würde aber keinen Sinn machen da die Klassen ihren Typ ja kennen.@Nexus: Was versteht man unter "explizite Typunterscheidungen". Kannst du ein Beispiel nennen?
class Base{}; class A : public Base{}; class B : public Base{}; int foo(Base& b) { if (IsA(b)) doItForA(b); else if (IsB(b)) doItForB(b); }Sowas deutet immer darauf hin, dass A und B in diesem Fall gar kein Base sind und somit mit der Vererbung was nicht stimmt.
-
pumuckl schrieb:
Eisflamme schrieb:
Meiner Meinung nach sollte das allerdings nicht allzu oft zum Einsatz kommen.
Würde eher sagen selten bis garnicht. Für Debugzwecke kann mans ausgeben, viel mehr kann man damit nicht anfangen, zumal die Ausgabe von type_info::name() nicht genauer spezifiziert ist.
Offtopic: Weiß wer, ob das in C++0x besser spezifiziert sein wird? Die Möglichkeit, zuverlässig an den Namen einer Klasse als String zu kommen, wäre z.B. für das plattformunabhängige Serialisieren von Objekten sehr praktisch. Mir ist auch schleierhaft, wieso das überhaupt der C++ Implementierung überlassen wird, was da zurückkommen soll.
-
Was hindert dich daran deiner Klasse ein entsprechendes Attribut mitzugeben? Wäre zwar nicht so schön, aber wenn man es benötigt. Hat nebenbei den Vorteil, du umschiffst damit Probleme, bei einer nicht Standardkonformen Umsetzung des Compilers.
-
hav a break schrieb:
Was hindert dich daran deiner Klasse ein entsprechendes Attribut mitzugeben? Wäre zwar nicht so schön, aber wenn man es benötigt. Hat nebenbei den Vorteil, du umschiffst damit Probleme, bei einer nicht Standardkonformen Umsetzung des Compilers.
Erstens:
hav a break schrieb:
...Wäre zwar nicht so schön...
Zweitens: In der Regel ist es besser, Dinge den Compiler erledigen zu lassen. Durch die ODR wird dabei z.B. implizit erzwungen, das Tags eindeutig sind.
-
Tachyon schrieb:
Zweitens: In der Regel ist es besser, Dinge den Compiler erledigen zu lassen. Durch die ODR wird dabei z.B. implizit erzwungen, das Tags eindeutig sind.
Wie du aber schon festgestellt hast, bekommst du diese Eindeutigkeit nur von Hand auch Compilerübergreifend hin. Und von Hand, heißt ja nicht, dass du es von Hand machen musst. Wenn man schlau ist lässt man sich so etwas durch das preprecessing erledigen.
-
Eigentlich habe ich nur eine ganz einfache Frage gestellt. Ich wollte keine Diskussion darüber lostreten, dass man es auch mit Gefrickel hinbekommen kann und ob dies gut oder schlecht ist.
-
Neulinger schrieb:
@Nexus: Was versteht man unter "explizite Typunterscheidungen". Kannst du ein Beispiel nennen?
Base* b = GetBasePointer(); if (typeid(*b) == typeid(Derived1)) DoSomething(); else if (typeid(*b) == typeid(Derived2)) DoSomethingElse(); else DoNothing();Geht auch mit
dynamic_cast. Warum das schlecht ist:Nexus (aus einem <a href= schrieb:
älteren Thread)">Einerseits sind Typunterscheidungen sehr fehleranfällig und müssen ständig mit der Klassenhierarchie konsistent bleiben. Wenn du Klassen berarbeitest, brauchst du an einem anderen Ort nochmals Code zu ändern. Bei
dynamic_casthast du zudem das Problem, dass die Reihenfolge derif-else-Statements richtig sein muss (abgeleitete müssen vor Basisklassen stehen). Beitypeidtritt das zwar nicht auf, dafür muss der Typ exakt stimmen, du kannst also mit Basisklassenabfragen keine abgeleiteten Klassen einschliessen. Ein weiteres Problem, das die Zentralisierung des Verhaltens mit sich bringt, ist die starke Abhängigkeit von Code. Bei der Typabfrage müssen nämlich alle Klassen vollständig bekannt sein. Besonders bei grösseren Projekten kann das die Kompilierzeit massiv beeinträchtigen, im Falle mehrerer Typabfragen in unterschiedlichen Modulen umso mehr.Das Wichtigste ist aber wohl, dass explizite Typunterscheidungen den Grundsatz der Polymorphie verletzen. Polymorphie (nicht nur dynamische) erlaubt es einem, Objekte mit unterschiedlichem Verhalten einheitlich anzusprechen, was eine starke Abstraktion ermöglicht. Mit manuellen Fallunterscheidungen verwirft man dieses Konzept und geht einen Schritt zurück – weg von objektorientierter Programmierung, in der ein Objekt selbst für sich schaut.
Im verlinkten Thread findet ihr übrigens auch eine Diskussion über RTTI .
-
Neulinger schrieb:
Ich kann momentan noch nicht nachvollziehen, was für einen Datentyp das typeid zurückgibt?!
Was sagt denn Dein C++ Buch dazu?
Neulinger schrieb:
type_info test = typeid(int); //Compiler sagt: Kein Zugriff auf private MemberDas bezieht sich sicherlich auf den Kopierkonstruktor des type_info-Typs. Siehe im entsprechenden Kapitel Deines C++ Buchs nach, wie das hier auszusehen hat.