'Typeid' contre 'typeof' en C ++
Question
Je me demande quelle est la différence entre typeid
et typeof
en C ++. Voici ce que je sais:
-
typeid
est mentionné dans la documentation de type_info qui est défini dans le fichier d'en-tête C typeinfo . -
typeof
est défini dans l'extension de GCC pour C et en C ++ Poussée bibliothèque.
En outre, le test est de code de test ici que j'ai créé où j'ai découvert que typeid
ne retourne pas ce que je pensais. Pourquoi?
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)
}
Sortie:
bash-3.2$ g++ -Wall main.cpp -o main
bash-3.2$ ./main
i
6Person
8Employee
P6Person
8Employee
La solution
Le langage C n'a pas de telle chose comme typeof
. Vous devez être à la recherche à un poste spécifique compilateur. Si vous parlez de typeof
de GCC, puis une fonction similaire est présent dans C ++ 11 par le decltype
mot-clé. Encore une fois, C ++ n'a pas un tel mot-clé typeof
.
typeid
est un opérateur de langage C ++ qui renvoie des informations d'identification de type au moment de l'exécution. Il retourne en fait un objet type_info
, ce qui est comparable l'égalité avec d'autres objets type_info
.
Notez que la propriété ne définie de l'objet type_info
retourné a est ses objets étant equality- et comparable non-égalité, à savoir type_info
décrivant différents types comparerai non égaux, alors que les objets de type_info
décrivant le même type doivent comparer égal. Tout le reste est défini par l'implémentation. Les méthodes qui renvoient différents « noms » ne sont pas garantis de retourner quoi que ce soit, et même pas garantie lisible par l'homme de retourner quoi que ce soit.
Notez également que ce qui précède implique probablement (bien que la norme ne semble pas mentionner explicitement) que les applications consécutives de typeid
au même type pourraient renvoyer différents objets type_info
(qui, bien sûr, doivent encore être égaux) .
Autres conseils
La principale différence entre les deux est le suivant:
- typeof est une construction de compilation et retourne le type tel que défini à la compilation
- typeid est une construction d'exécution et donne donc des informations sur le type de la valeur d'exécution.
typeof Référence: http://www.delorie.com/gnu/docs /gcc/gcc_36.html
typeid Référence: https://en.wikipedia.org/wiki/Typeid
typeid
peut fonctionner à l'exécution, et renvoyer un objet décrivant le type de l'objet de l'exécution , qui doit être un pointeur vers un objet d'une classe avec des méthodes virtuelles afin de RTTI (run-time les informations de type) à stocker dans la classe. Il peut également donner le type de compilation d'une expression ou un nom de type, sinon un pointeur sur une classe avec des informations de type run-time.
typeof
est une extension GNU, et vous donne le type d'une expression au moment de la compilation. Cela peut être utile, par exemple, en déclarant des variables temporaires dans les macros qui peuvent être utilisés sur plusieurs types. En C ++, vous généralement utiliser modèles à la place.
Répondre à la question supplémentaire:
mon code de test suivant pour typeid ne pas de sortie le nom du type correct. ce qui ne va pas?
Il n'y a rien de mal. Ce que vous voyez est la représentation de chaîne du nom de type. La norme C ++ ne force pas compilateurs pour émettre le nom exact de la classe, il est juste à l'implémenteur (fournisseur de compilateur) pour décider ce qui est approprié. En bref, les noms sont à compilateur.
Ce sont deux outils différents. typeof
renvoie le type d'une expression, mais ce n'est pas standard. En C ++ 0x, il y a quelque chose appelé decltype
qui fait le même travail AFAIK.
decltype(0xdeedbeef) number = 0; // number is of type int!
decltype(someArray[0]) element = someArray[0];
Alors que typeid
est utilisé avec des types polymorphes. Par exemple, permet de dire que cat
dérive animal
:
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 fournit le type des données lors de l'exécution, quand on a demandé. Typedef est une construction de compilation qui définit un nouveau type comme indiqué par la suite. Il n'y a pas typeof en C ++ Sortie apparaît comme (présentée comme commentaires inscrits):
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
Vous pouvez utiliser demangle Boost pour accomplir un beau nom à la recherche:
#include <boost/units/detail/utility.hpp>
et quelque chose comme
To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);