'Typeid' versus 'Typeof' in C ++
Frage
Ich frage mich, was der Unterschied zwischen typeid
und typeof
in C ++. Hier ist, was ich weiß:
-
typeid
ist in der Dokumentation erwähnt für type_info , die in definiert ist die C ++ Header-Datei Typeinfo . -
typeof
ist in der GCC-Erweiterung für C definiert ist und in der C ++ Boost- Bibliothek.
Auch hier ist Testcode Test, dass ich erstellt habe, wo ich entdeckt habe, dass typeid
nicht zurück, 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
Lösung
C ++ Sprache hat nicht so etwas wie typeof
. Sie müssen zu einer bestimmten Compiler-spezifischer Erweiterung suchen werden. Wenn Sie sich über GCC typeof
sprechen, dann ein ähnliches Feature ist in C ++ 11 durch das Schlüsselwort decltype
. Auch hier hat C ++ keine solche typeof
Schlüsselwörter.
typeid
ist eine C ++ Sprache, die Operator-Typ-Identifikationsinformation zur Laufzeit zurückkehrt. Es gibt im Grunde ein type_info
Objekt, das mit anderen type_info
Objekten Gleichheit vergleichbar ist.
Beachten Sie, dass die einzige definierte Eigenschaft des zurück type_info
Objekt hat, ist seine gleichstellungs und Nicht-Gleichheit-vergleichbar sein, dh type_info
Objekte verschiedene Arten beschreiben, sind nicht gleich, ist während type_info
Objekte beschreiben die gleiche Art zum Vergleichen gleich. Alles andere ist die Implementierung definiert. Methoden, die verschiedene „Namen“ sind nicht garantiert Rückkehr etwas für Menschen lesbaren und auch nicht garantiert Rückkehr irgendetwas überhaupt zurück.
Beachten Sie auch, dass die oben wahrscheinlich impliziert (auch wenn der Standard scheint nicht explizit zu erwähnen), dass aufeinanderfolgende Anwendungen von typeid
auf die gleiche Art unterschiedliche type_info
Objekte zurückgeben könnten (was natürlich immer noch gleich vergleichen müssen) .
Andere Tipps
Der wesentliche Unterschied zwischen den beiden ist die folgende
- typeof ist eine Kompilierung-Konstrukt und gibt den Typ wie bei der Kompilierung definiert
- typeid ist ein Runtime-Konstrukt und somit gibt Auskunft über den Laufzeittyp des Wertes.
typeof Referenz: http://www.delorie.com/gnu/docs /gcc/gcc_36.html
typeid Referenz: https://en.wikipedia.org/wiki/Typeid
typeid
zur Laufzeit arbeiten kann, und gibt ein Objekt beschreibt den Laufzeittyp des Objekts , die mit virtuellen Methoden, um auf ein Objekt eine Klasse sein, um einen Zeiger müssen für RTTI (run-time Typinformationen) in der Klasse gespeichert werden. Es kann auch die Kompilierung Typen eines Ausdrucks oder einen Typ Namen geben, wenn nicht einen Zeiger auf eine Klasse mit Laufzeittypinformationen gegeben.
typeof
ist eine GNU-Erweiterung, und gibt Ihnen die Art eines Ausdrucks bei der Kompilierung. Dies kann nützlich sein, zum Beispiel in der temporären Variablen in Makros deklariert, die auf mehreren Arten verwendet werden. In C ++, würden Sie in der Regel verwenden Vorlagen statt.
Die Beantwortung der Zusatzfrage:
mein folgender Testcode für typeid tut nicht ausgegeben den richtigen Typ Namen. was ist los?
Es ist nichts falsch. Was Sie sehen, ist die String-Darstellung des Typnamen. Die Standard-C ++ Compiler nicht zwingen, den genauen Namen der Klasse zu emittieren, ist es nur bis zu dem Implementierer (Compiler-Anbieter) zu entscheiden, was geeignet ist. Kurz gesagt, sind die Namen an den Compiler auf.
Das sind zwei verschiedene Werkzeuge. typeof
gibt den Typ eines Ausdrucks, aber es ist nicht Standard. In C ++ 0x gibt es etwas decltype
genannt, was macht die gleiche Arbeit AFAIK.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
Während typeid
mit polymorphen Typen verwendet. Zum Beispiel kann diesen cat
herleitet animal
sagen:
animal* a = new cat; // animal has to have at least one virtual function
...
if( typeid(*a) == typeid(cat) )
{
// the object is of type cat! but the pointer is base pointer.
}
typeid stellt die Art der Daten zur Laufzeit, wenn gefragt. Typedef ist ein Kompilierung-Konstrukt, das eine neue Art definiert wie danach angegeben. Es gibt keine typeof in C ++ Ausgabe erscheint als (wie beschriftet Kommentare angezeigt):
std::cout << typeid(t).name() << std::endl; // i
std::cout << typeid(person).name() << std::endl; // 6Person
std::cout << typeid(employee).name() << std::endl; // 8Employee
std::cout << typeid(ptr).name() << std::endl; // P6Person
std::cout << typeid(*ptr).name() << std::endl; //8Employee
Sie können die Boost-demangle verwenden, um einen gut aussehenden Namen zu erreichen:
#include <boost/units/detail/utility.hpp>
und so etwas wie
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);