C++ typeid关键字详解
来源:互联网 发布:网页在线客服源码 编辑:程序博客网 时间:2024/06/08 16:38
http://blog.csdn.net/gatieme
typeid关键字
注意:typeid是操作符,不是函数。这点与sizeof类似)
运行时获知变量类型名称,可以使用 typeid(变量).name()
需要注意不是所有编译器都输出”int”、”float”等之类的名称,对于这类的编译器可以这样使用
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
RTTI(Run-Time Type Identification)-运行时类型识别
在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。
在C++中,为了支持RTTI提供了两个操作符:dynamic_cast
和typeid
dynamic_cast允许运行时刻进行类型转换,从而使程序能够在一个类层次结构中安全地转化类型,与之相对应的还有一个非安全的转换操作符static_cast,因为这不是本文的讨论重点,所以这里不再详述,感兴趣的可以自行查阅资料。
typeid是C++的关键字之一,等同于sizeof这类的操作符。typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件typeinfo中定义,稍后我们看一下vs和gcc库里面的源码),它的表达式有下图两种形式。
实现机制与使用技巧
type_info类对象类别判别
对象类别判别分析
如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算;
否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。
ISO C++标准并没有确切定义type_info
,它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作(在之后的章节中我会来分析type_info类文件的源码)
type_info类提供了public虚 析构函数,以使用户能够用其作为基类。它的默认构造函数和拷贝构造函数及赋值操作符都定义为private,所以不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符(由此可见,如果把typeid看作函数的话,其应该是type_info的 友元)。type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此,见后面的程序),这具体由编译器的实现所决定的,标准只要求实现为每个类型返回唯一的字符串。
type_info类源代码
使用sudo find / -name typeinfo.h
来查找源码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
示例1-基本数据类型
下表列出了使用typeid操作符的表达式的值
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
操作符typeid返回的是一个type_info类(用于描述数据类型的一个系统类)对象的引用。这个操作符可以用于表达式和类型名(包括自定的数据类型,比如类)。
示例2-类对象
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
假设我们根据例2中定义的两个类来定义如下指针:
- 1
- 1
下表将给出使用typeid操作符的结果。
对于表达式typeid(p),同样,因为p是base*类型的指针,因此typeid(p) == typeid(base*)为真,而typeid(p) == typeid(derived*)为假。而对于表达式typeid(*p),由于此时的基类不具有多态性,因而*p将会采用编译期类型来计算,编译期*p是base对象,因此表达式typeid(*p) == typeid(derived)为假,typeid(*p) == typeid(base)为真。
示例3-带虚函数的基类
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
假设我们如本例所示定义了两个类base类和derived类,基于这两个类定义,我们定义指针如下:
- 1
- 1
下表将给出使用typeid操作符的结果。
对于表达式typeid(p),因为p是base*类型的指针,因此typeid(p) == typeid(base*)为真,而typeid(p) == typeid(derived*)为假。而对于表达式typeid(*p),因为base类具有多态性,因而在计算typeid(*p)时会根据运行时p所指向的实际类型去计算,而本例中p指向的是派生类对象,因此表达式typeid(*p) == typeid(derived)为真,typeid(*p) == typeid(base)为假。
异常处理bad_typeid
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
参照
【C++】typeinfo.h
C++中的typeid关键字
- C++ typeid关键字详解
- C++ typeid关键字详解
- C/C++ 之 typeid详解
- 关键字:typeid
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- typeid详解
- 不辜负
- UE4 蓝图工程转c++工程失败
- JAVA正则表达式
- 程序员面试金典: 9.7位操作 7.3判定直角坐标系上两直线是否相交
- Oracle中的SQL * PLUS与PL/SQL笔记整理,SQL Plus输出结果格式化笔记整理
- C++ typeid关键字详解
- getchar返回值类型、EOF、if语句
- tcp.udp
- Pattern Recognition and Machine Learning 第八章 贝叶斯网络
- java 基本数据类型
- eclipse切换workspace
- TCP和UDP的区别与联系
- 二元树的深度
- HTML入门学习笔记--认识HTML(1)