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
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
那么汇编是
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
http://blog.csdn.net/is2120/archive/2011/05/10/6410096.aspx
@IS2120#CNBLOGS.T2169364049[T1,L65,R1,V259]:备忘
$ € ₤ ₭ ₪ ₩ ₮ ₦ ₱ ฿ ₡ ₫ ﷼ ¥ ﷼ ₫ ₡ ฿ ₱ ₦ ₮ ₩ ₪ ₭ ₤ € $