0
点赞
收藏
分享

微信扫一扫

typeid 使用说明


//z 2011-05-10 20:04:52@is2120




tag: c++ typeid 实现 使用 用法


 


typeid是什么?
是c++的一个操作符,用于获取一个表达式的类型


 


typeid如何实现

typeid (5.3.7): find vtable, through that find most derived class object, then extract type_info from that object's vtable. It is still very slow comparing with function call;


typeid使用的几种情况:


 


1. 操作类型是内置类型或是常量

int i;
 cout << typeid(i).name() << endl;//z 输出:int
 cout << typeid(0.0f).name() << endl; //z 输出:double 

    

 

  //z 2011-05-10 20:04:52@is2120


2. 操作类型为类类型
分两种情况
2.1 类不带虚函数

typeid会指出操作数的类型,而不是底层对象的类型。
 class B{};
 class D:public B {}; 

    

 
D d;
 B* pb = &d;//z 此时pb实际指向的底层类型为DERIVED 

    

 
cout << typeid(*pd).name() <<endl;//z 输出B

 (在vc下,使用typeid的时候,如果typeid施加给的类型是没有vptr的class或者根本不是class
那么汇编是
mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
也就是编译器生成一个简单的type_info对象的表,并且在编译期静态决定下标,做一个简单查表操作。 )



2.2 带虚函数

class B{public: virtual void foo(){}};
 class D:public B{}; 

    

 
D d;
 B* pb = &d;
 cout << typeid(*pb).name() << endl;//z 输出D


 


3. 操作类型为一个指针时
就如同1一样了,会输出操作数的类型,而不是其底层指向的类型。


 

一个例子:
 //z 2011-05-10 20:04:52@is2120 

    

 
#include <iostream>
 #include <typeinfo> 

    

 
using namespace std;
 

    

 
class B
 {
 public:
     virtual void foo(){};
 }; 

    

 
class D : public B
 {
 public:
     virtual void foo(){};
 }; 

    

 
int main()
 {
     D d;
     B& b = d;
     B* pb = &d;
     D* pd = dynamic_cast<D*>(&b); 

    

 
    cout << typeid(b).name() << endl;
     cout << typeid(d).name() << endl;
     //z 这里输出 B*是因为pb是一个指针,而不是一个类类型。
     //z 为了获取到派生类的类型,typeid的操作对象必须是一个类类型
     cout << typeid(pb).name() << endl;
     cout << typeid(*pb).name() << endl;
     cout << typeid(pd).name() << endl;
     cout << typeid(*pd).name() << endl;
 }

 


/* 输出如下:
class D
class D
class B *
class D
class D *
class D
*/


 


4. 是否会对效率造成影响(cost,overhead)
为实现typeid,需要在vtable中添加一个指针,指向type information structure。
同普通的成员函数(function call)比起来,会慢一些
但是具有虚函数的类总是创建和初始化vtable,这里只是增加了一个指针,所以不会带来什么性能上的开销。


 


5. 环境
vc下,通过/GR 启用RTTI
gcc默认是启用的,可以通过 -fno-rtti 选项禁用

//z 2011-05-10 20:04:52@is2120


举报

相关推荐

0 条评论