C++ RTTI介绍
一、定义:RTTI:Run Time Type Identification ,执行时类型识别:指程序可以使用基类的指针或引用来检索其所指对象的实际派生类型。
二、使用方式:C++中有两个操作符提供RTTI:
(1)typeid 操作符:返回指针或引用所指对象的实际类型。
(2)dynamic_cast 操作符:将基类类型的指针或引用安全地转换为派生类型的指针和引用。
注:此二操作符仅仅为带有一个或多个虚函数的类返回动态类型信息----即在执行时执行RTTI操作符;对于其它类型则返回静态类型的信息---即在编译时计算RTTI操作符。
三、详细介绍:
(1)typeid
头文件:# include<typeinfo>
语法--两种形式:typeid (type) 、typeid (expression)即随意表达式或类型名。 常见的用途:比較两个表达式的类型。或者将表达式的类型与特定类型相比較。
typeid返回类型:const type_info&;
详细定义例如以下:
- class type_info{
- public:
- virtul ~type_info();
- bool operator == (const type_info&rhs)const;
- bool operator != (const type_info&rhs)const;
- bool before(const type_info&rhs)const;
- const char* name()const;
- private:
- type_info(const type_info& rhs);
- type_info& operator=(const type_info& rhs);
- }
接口说明:
operator ==和operator!=:比較操作符。返回两个类型是否为(或不为)同一类型(注:基类和派生类不为同一类型! )。
before:若在类型排序中。该类型先于rhs的类型则返回true。 name:返回类型相应的名字(详细所用的值,依赖于详细编译器)(以\0结束的字符串)。
注意:type_info类的默认构造函数和复制构造函数以及赋值操作符都定义为private,故不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符。 样例:(来源)
- #include <iostream>
- #include <typeinfo>
- using namespace std;
- struct Base {};
- struct Derived : Base {};
- struct Poly_Base {virtual void Member(){}};
- struct Poly_Derived: Poly_Base {};
- int main() {
- int a;
- int * pa;
- cout << "int is: " << typeid(int).name() << endl;
- cout << " a is: " << typeid(a).name() << endl;
- cout << " pa is: " << typeid(pa).name() << endl;
- cout << "*pa is: " << typeid(*pa).name() << endl << endl;
- Derived derived;
- Base* pbase = &derived;
- cout << "derived is: " << typeid(derived).name() << endl;
- cout << "*pbase is: " << typeid(*pbase).name() << endl;
- cout << "same type? ";
- cout << ( typeid(derived)==typeid(*pbase) ) << endl << endl;
- Poly_Derived polyderived;
- Poly_Base* ppolybase = &polyderived;
- cout << "polyderived is: " << typeid(polyderived).name() << endl;
- cout << "*ppolybase is: " << typeid(*ppolybase).name() << endl;
- cout << "same type? ";
- cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;
- return 0;
- }
执行结果:(尝试了两个编译环境:g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4) 和 VC6.0)
G++结果:
VC6.0结果:
注:尽管 typeid(*ppolybase)返回派生类类型。可是 typeid(ppolybase)依然是返回基类指针类型。 同理,引用相似:假设r是引用,typeid(r)返回派生类类型,typeid(&r)则依然返回基类类型。
注意到:两个编译环境的执行结果不一样---即typeid在不同编译环境下返回的结果是不一致的! 为什么会这样呢?
由于:标准C++规定,type_info类的确切定义随编译器而变化,仅仅要保证全部的实现提供以上的基本操作即可(见类定义)。即详细实现细节。各编译器厂商可自行决定。
注:在VC6.0执行时,记得把编译选项加上“/GR“ ,否则编译时会出现Warning(project--设置--C/C++---project选项)。 由于VC6.0默认不开启RTTI。 (2)dynamic_cast
语法形式:dynamic_cast<T>(v) ,将对象 v 转换为类型T的对象。
前提:v 要么为指向其派生类对象的基类指针,要么为引用其派生类对象的基类对象。否则。v 返回NULL(为指针时)或抛出std::bad_cast(在头文件<typeinfo>中定义)异常(为引用类型时);而T为所期望的派生类指针类型或派生类引用类型。 且。v指向的基类里必须包括虚函数,即多态类型。否则编译出错。 经常使用写法:
I、Poly_Derived* derivedPtr = dynamic_cast<Poly_Derived*>(ppolybase);//转换为指向Poly_Derived 型的指针,失败返回NULL;
II、Poly_Derived& derivedRef = dynamic_cast<Poly_Derived&>(polyderived); //转换为Poly_Derived 引用,失败时抛出bad_cast异常。
详细见样例:
- #include <iostream>
- #include <typeinfo>
- using namespace std;
- struct Poly_Base {virtual void Member(){}};
- struct Poly_Derived: Poly_Base {};
- int main() {
- Poly_Derived polyderived;
- Poly_Base* ppolybase = &polyderived;
- Poly_Base& rpolybase = polyderived;
- if(Poly_Derived* derivedPtr = dynamic_cast<Poly_Derived*>(ppolybase))//base pointer
- {
- cout<<"dynamic_cast pointer success."<<endl;
- }
- else
- {
- cout<<"dynamic_cast pointer fail!"<<endl;
- }
- try{
- const Poly_Derived& derivedRef = dynamic_cast<const Poly_Derived&>(rpolybase);
- cout<<"dynamic_cast reference success."<<endl;
- }catch(bad_cast){
- cout<<"dynamic_cast reference fail."<<endl;
- }
- cout <<"same type? ";
- cout << ( typeid(rpolybase)==typeid(*ppolybase) ) << endl;
- return 0;
- }
执行结果:
原文链接: http://blog.csdn.net/heyabo/article/details/8348624
參考文章:
1. http://www.cplusplus.com/reference/typeinfo/type_info/
2. http://en.cppreference.com/w/cpp/language/typeid
3. http://stackoverflow.com/questions/1986418/typeid-and-typeof-in-c
4. http://renhl252.blog.163.com/blog/static/2122100720098229281284/
C++ RTTI介绍的更多相关文章
- c++之RTTI介绍
本文介绍c++的RTTI的基本用法,并初步研究RTTI的实现原理. 1. 什么是RTTI RTTI即运行时类型识别(runtime type identification),用于判断指针或引用所绑定对 ...
- RTTI
RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. 编辑本段RTTI介绍 RTTI提 ...
- Delphi 类的类 class of 用法
http://blog.csdn.net/blue_morning/article/details/8815609 Delphi 类的类 class of 用法 这个概念本来在一个关于Delphi ...
- Delphi 类引用 Class Reference 元类 MetaClass 用法
delphi中类引用的使用实例 类引用类引用(Class Reference)是一种数据类型,有时又称为元类(MetaClass),是类的类型的引用.类引用的定义形式如下: class of type ...
- Java系列笔记(2) - Java RTTI和反射机制
目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这 ...
- RTTI (Run-Time Type Identification,通过运行时类型识别) 转
参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. RTTI提供了以下两个 ...
- C++中的RTTI机制解析
RTTI RTTI概念 RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型. RTTI ...
- C++ RTTI
一.定义:RTTI:Run Time Type Identification ,运行时类型识别:指程序能够使用基类的指针或引用来检索其所指对象的实际派生类型.二.使用方式:C++中有两个操作符提供RT ...
- C++重载(主要介绍使用友元函数重载)
重载限制 多数C++运算符都可以用下面的方式重载.重载的运算符不必是成员函数,但必须至少有一个操作数是用户自定义的类型.下面详细介绍C++对用户定义的运算符重载的限制. 1 重载后的运算符必须至少有一 ...
随机推荐
- 未来IT行业的掌控者
(题外话,我发现很多高手都喜欢讲代码实现,喜欢贴代码贴图,我个人不大喜欢这种方式,我觉得最重要的是思想,是想法,具体的实现代码实现步骤由读者自己去实现.这纯属我个人喜好,望各大内高手勿喷,可能是本人水 ...
- iOS Cell异步图片加载优化,缓存机制详解
最近研究了一下UITbleView中异步加载网络图片的问题,iOS应用经常会看到这种界面.一个tableView上显示一些标题.详情等内容,在加上一张图片.这里说一下这种思路. 为了防止图片多次下载, ...
- PHP笔录(韩顺平)
这里记录下韩顺平视频学习记录 http://www.php.cn/code/11753.html
- maven release插件将一版本发布到仓库中时Return code is: 401, ReasonPhrase:Unauthorized
需要在maven的setting.xml中配置servers.server节点,其值为nexus的对应的repository的id以及用户名及密码 <servers> <server ...
- 关闭警告&关闭eslint
1.main.js中添加 vue.config.productiontip = false 这样即可去除警告! 第一个除了那个配置意外,还需要将 NODE_ENV 设置为 production 参 ...
- jdk11 eclipse下开启ZGC
平台支持 ZGC目前只在Linux/x64上可用,如果有足够的需求,将来可能会增加对其他平台的支持. 对的,目前只支持64位的linux系统. -_-' eclipse.ini配置: -XX:+Unl ...
- 216种Web安全颜色
216种Web安全颜色 全部 JavaScript HTML5 jQuery CSS EXT Ajax Web综合 界面设计 DWR 锁定老帖子 主题:216种Web安全颜色 精华帖 (0) :: ...
- [HEOI2013]ALO
题目描述: 现在你拥有 n 颗宝石,每颗宝石有一个能量密度,记为 ai,这些宝石的能量 密度两两不同.现在你可以选取连续的一些宝石(必须多于一个)进行融合,设 为 ai, ai+1, …, aj,则融 ...
- 创建Javaweb项目及MyEclipse视图的配置
在myEclipse里--右键new--Web Project 视图的配置--Window--Show View-Other在里面输入要找的视图例如(servers)或者直接 Window--rese ...
- Codeforces Round #352 (Div. 2),A题与B题题解代码,水过~~
->点击<- A. Summer Camp time limit per test 1 second memory limit per test 256 megabytes input s ...