在C ++中使用“typeid”与“typeof”
我想知道在C + + typeid
和typeof
之间有什么区别。 以下是我所知道的:
-
在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标准似乎没有明确提到它)连续的typeid
types对同一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);