Ich frage mich, was der Unterschied zwischen typeid
und typeof
in C ++ ist. Folgendes weiß ich:
typeid
wird in der Dokumentation zu type_info erwähnt, die in der C ++ - Headerdatei typeinfo definiert ist .typeof
wird in der GCC-Erweiterung für C und in der C ++ Boost- Bibliothek definiert.
Außerdem habe ich hier einen Testcodetest erstellt, bei dem ich festgestellt habe, dass er typeid
nicht das zurückgibt, was ich erwartet hatte. Warum?
main.cpp
#include <iostream>
#include <typeinfo> //for 'typeid' to work
class Person {
public:
// ... Person members ...
virtual ~Person() {}
};
class Employee : public Person {
// ... Employee members ...
};
int main () {
Person person;
Employee employee;
Person *ptr = &employee;
int t = 3;
std::cout << typeid(t).name() << std::endl;
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time)
std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a pointer
// to a polymorphic class)
}
Ausgabe:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
name()
ist implementierungsdefiniert. Es muss kein gültiger C ++ - Bezeichnername sein, sondern nur etwas , das den Typ eindeutig identifiziert. Ihre Implementierung verwendet anscheinend das allgemeine Name-Mangling-Schema des Compilers.Antworten:
In der C ++ - Sprache gibt es keine
typeof
. Sie müssen sich eine compilerspezifische Erweiterung ansehen. Wenn Sie über GCCs sprechentypeof
, ist eine ähnliche Funktion in C ++ 11 über das Schlüsselwort vorhandendecltype
. Auch hier hat C ++ kein solchestypeof
Schlüsselwort.typeid
ist ein C ++ - Sprachoperator, der zur Laufzeit Informationen zur Typidentifikation zurückgibt. Grundsätzlich wird eintype_info
Objekt zurückgegeben, das mit anderentype_info
Objekten gleichwertig ist.Beachten Sie, dass die einzige definierte Eigenschaft des zurückgegebenen
type_info
Objekts darin besteht, dass es gleich und nichttype_info
gleich ist , dh Objekte, die verschiedene Typen beschreiben, müssen ungleich verglichen werden, währendtype_info
Objekte, die denselben Typ beschreiben, gleich vergleichen müssen. Alles andere ist implementierungsdefiniert. Bei Methoden, die verschiedene "Namen" zurückgeben, wird nicht garantiert, dass sie von Menschen gelesen werden, und es wird auch nicht garantiert, dass sie überhaupt etwas zurückgeben.Beachten Sie auch, dass das oben Gesagte wahrscheinlich impliziert (obwohl der Standard dies nicht explizit zu erwähnen scheint), dass aufeinanderfolgende Anwendungen
typeid
desselben Typs möglicherweise unterschiedlichetype_info
Objekte zurückgeben (die natürlich immer noch gleich verglichen werden müssen).quelle
decltype
? Ich bin nicht sicher, was die allgemeine Richtlinie ist, aber da die Frage markiert ist,C++
würde ich erwarten, dass sie sich auf den neuesten Standard bezieht. Die Frage neu zu markieren,C++03
wäre imho auch eine Option. Ich persönlich bin manchmal ziemlich verwirrt, da ich preC ++ 11 bei der Arbeit verwenden muss und manchmal nicht sicher bin, was "pre11" oder "post11" ist.decltype
ist kein Ersatz fürtypeof
.typeof
funktioniert auch bei Typen, währenddecltype
dies nicht der Fall ist. Zum Beispieltypeof(int)
istint
whiledecltype(int)
ein Fehler.type_info
Objekte, die verschiedene Typen beschreiben, müssen ungleich vergleichen" . Dies ist eigentlich nicht garantiert . Der Ungleichungsoperator wurde in C ++ 20 entfernt, um (ich nehme an) davon abzuhalten, sich auf verschiedene Typen zu verlassen, die ungleich vergleichen. Aber wenn Sie darüber nachdenken, ist Gleichheit nicht sicher, wenn Ungleichheit nicht sicher ist.Der Hauptunterschied zwischen den beiden ist der folgende
Referenztyp: http://www.delorie.com/gnu/docs/gcc/gcc_36.html
typeid Referenz: https://en.wikipedia.org/wiki/Typeid
quelle
typeid
kann zur Laufzeit arbeiten und ein Objekt zurückgeben, das den Laufzeittyp des Objekts beschreibt. Dies muss ein Zeiger auf ein Objekt einer Klasse mit virtuellen Methoden sein, damit RTTI (Laufzeittypinformationen) in der Klasse gespeichert werden können. Es kann auch den Kompilierungszeittyp eines Ausdrucks oder einen Typnamen angeben, wenn kein Zeiger auf eine Klasse mit Laufzeittypinformationen angegeben wird.typeof
ist eine GNU-Erweiterung und gibt Ihnen den Typ eines beliebigen Ausdrucks zur Kompilierungszeit an. Dies kann beispielsweise beim Deklarieren temporärer Variablen in Makros hilfreich sein, die für mehrere Typen verwendet werden können. In C ++ verwenden Sie normalerweise stattdessen Vorlagen .quelle
typeid
wird jeder Ausdruck akzeptiert, nicht nur diejenigen, die Objekte mit virtuellen Methoden auswerten. Darüber hinaustypeid
wird eine Art annehmen Namen , nicht nur einen Ausdruck. Sie können sagentypeid(5)
odertypeid(std::string)
wenn Sie wollen.typeid
kann Informationen zum Laufzeittyp zurückgeben, falls verfügbar, bietet jedoch Informationen zum Kompilierungszeittyp für alles andere.Beantwortung der Zusatzfrage:
Es ist nichts falsch. Was Sie sehen, ist die Zeichenfolgendarstellung des Typnamens. Das Standard-C ++ zwingt Compiler nicht dazu, den genauen Namen der Klasse auszugeben. Es ist nur Sache des Implementierers (Compiler-Hersteller), zu entscheiden, was geeignet ist. Kurz gesagt, die Namen liegen beim Compiler.
Dies sind zwei verschiedene Werkzeuge.
typeof
Gibt den Typ eines Ausdrucks zurück, ist jedoch kein Standard. In C ++ 0x gibt es etwas,decltype
das den gleichen Job AFAIK macht.Während
typeid
bei polymorphen Typen verwendet wird. Zum Beispiel kann sagen , dasscat
herleitetanimal
:quelle
typeid gibt den Typ der Daten zur Laufzeit an, wenn Sie dazu aufgefordert werden. Typedef ist ein Konstrukt zur Kompilierungszeit, das einen neuen Typ definiert, wie danach angegeben. Es gibt keinen Typ in C ++. Die Ausgabe wird wie folgt angezeigt (angezeigt als eingeschriebene Kommentare):
quelle
Sie können Boost Demangle verwenden, um einen gut aussehenden Namen zu erhalten:
und so ähnlich
quelle