在C ++中使用“typeid”与“typeof”

我想知道在C + + typeidtypeof之间有什么区别。 以下是我所知道的:

  • 在C ++头文件typeinfo中定义的type_info文档中提到了typeid 。

  • typeof在C的GCC扩展和C ++ Boost库中定义。

另外,这里是我创build的testing代码testing,发现typeid不会返回我所期望的。 为什么?

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) } 

输出:

 bash-3.2$ g++ -Wall main.cpp -o main bash-3.2$ ./main i 6Person 8Employee P6Person 8Employee 

C ++语言没有types的东西。 您必须查看一些编译器特定的扩展。 如果您正在讨论GCC的types,那么类似的function通过关键字decltype在C ++ 11中提供。 再一次,C ++没有这样的typeof关键字。

typeid是一个C ++语言运算符,它在运行时返回types标识信息。 它基本上返回一个type_info对象,它与其他type_info对象相等。

请注意,返回的type_info对象唯一定义的属性是它的等同性和非等同性可比性,即描述不同types的type_info对象应比较不等于,而描述相同types的type_info对象必须相等。 其他一切都是实现定义的。 返回各种“名称”的方法不保证能够返回任何人类可读的内容,甚至不能保证返回任何东西。

还要注意的是,上面可能意味着(尽pipe标准似乎没有明确提到它)连续的typeidtypes对同一types的应用可能返回不同的type_info对象(当然,这仍然需要进行比较)。

两者的主要区别如下

  • typeof是一个编译时结构,并返回编译时定义的types
  • typeid是一个运行时结构,因此提供了有关该值的运行时types的信息。

types的Refenence: http : //www.delorie.com/gnu/docs/gcc/gcc_36.html

typeid Rfeerence: http : //en.wikipedia.org/wiki/Typeid

typeid可以在运行时运行,并返回一个描述对象运行时types的对象,该对象必须是一个指向虚拟方法的类的对象,以便RTTI(运行时types信息)被存储在类中。 如果没有给出具有运行时types信息的类的指针,它也可以给出expression式或types名称的编译时间types。

typeof是一个GNU扩展,在编译时给你任何expression式的types。 例如,在可能用于多种types的macros中声明临时variables时,这可能很有用。 在C ++中,您通常会使用模板 。

回答额外的问题:

我下面的typeidtesting代码不会输出正确的types名称。 怎么了?

没有什么错。 你看到的是types名称的string表示。 标准的C ++不会强制编译器发出类的确切名称,只是由实现者(编译器供应商)决定什么是合适的。 总之,这些名字取决于编译器。


这是两种不同的工具。 typeof返回expression式的types,但不是标准的。 在C ++ 0x中有一个叫做decltype东西,可以做同样的工作AFAIK。

 decltype(0xdeedbeef) number = 0; // number is of type int! decltype(someArray[0]) element = someArray[0]; 

typeid与多态types一起使用。 例如,让我们说cat导出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在运行时提供数据的types。 Typedef是一个编译时间结构,它定义了一个新的types。 在C ++中没有typeof输出(显示为注释):

 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 

您可以使用Boost demangle来完成一个漂亮的名字:

 #include <boost/units/detail/utility.hpp> 

和类似的东西

 To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this);