C++ RTTI中dynamic_cast的用法

我们知道在C++中基类的指针和引用可以指向派生类,因为这是安全的,派生类一定包含了基类
需要的所有的属性和方法,这是向上转换,我们同时还知道虚函数可以随着指针和引用指向的
对象不同而使用不同的方法,这是虚函数的自适应。
打个例子:

点击(此处)折叠或打开

  1. class testb
  2. {
  3.         private:
  4.                 int a;
  5.         public:
  6.                 testb(int ai){a=ai;}
  7.                 virtual void show(void) const
  8.                 {
  9.                         cout<<a<<endl;
  10.                 }
  11.                 virtual ~testb(){}
  12. };
  13. class testc:public testb
  14. {
  15.         private:
  16.                 int b;
  17.         public:
  18.                 testc(int ai,int bi):testb(ai),b(bi){}
  19.                 virtual void show(void) const
  20.                 {
  21.                         cout<<"test:"<<b<<endl;
  22.                 }
  23.                 void show2(void) const
  24.                 {
  25.                         cout<<"test2:"<<b<<endl;
  26.                         testb::show();
  27.                 }
  28.                 virtual ~testc(){}
  29. };

testb *p;
testc a(1,2);
testb b(1);
p可以指向派生类
p= &a;
p->show() 为派生类的testc::show();
p可以指向基类
p=&b;
p->show() 为基础类的testb::show();

因为show()虚函数,这样是可以完成。

但是我们考虑另外一种情况
testb *p;
testc a(1,2);
p= &a;
p->show2(); 是否能够按照我们预想的调用到testc::show2()呢
答案是否定的,因为show2()根本就不是虚函数.只有虚函数才有这样的自适应性,也就是根据指向对象的不同而调用合适的方法。
那么我们是否可以
(testc* )p;
这样处理呢,因为我们知道p指向是一定testc的派生类,我们将p指针转换后为testc*是安全的,这样处理是可以的。
这里谈到了安全,什么时候是不安全的呢?考虑如下情况:
testb *p;
testb b(1);
p= &b;
(testc* )p;
这就是不安全的,因为做强制转换将指向基础类 testb的指针转换为派生类testc指向那么void show2(void) const是不存在的。
当然这里我们可以人为判断,但是不是任何时候都可以这样,比如程序大了过后。我们需要一种方法来完成这样的判断工作,
那么引入了RTTI dynamic_cast
dynamic_cast<Type *>(pt)
成功pt转换为Type类型指针失败返回0及空指针。
最后演示一下用法头文件就是刚才给出的

点击(此处)折叠或打开

  1. #include<iostream>
  2. #include"dynamic_cast.h"
  3. using namespace std;
  4. int main(void)
  5. {
  6.         testb *p;
  7.         testb a(1);
  8.         testc b(1,100);
  9.         p=&a;
  10.         testc *q1 = dynamic_cast<testc*>(p);
  11.         if(!q1)
  12.         {
  13.                 cout<<"dynamic check cast of q1 failed!!"<<endl;
  14.         }
  15.         else
  16.         {
  17.                 q1->show2();
  18.         }
  19.         p=&b;
  20.         testc *q2 = dynamic_cast<testc*>(p);
  21.         if(!q2)
  22.         {
  23.                 cout<<"dynamic check cast of q2 failed!!"<<endl;
  24.         }
  25.         else
  26.         {
  27.                 q2->show2();
  28.         }
  29. }

输出:
dynamic check cast of q1 failed!!
test2:100
1

没有问题testc *q1 = dynamic_cast<testc*>(p);
返回了一个空指针返回了dynamic check cast of q1 failed!!
第二个

testc *q2 = dynamic_cast<testc*>(p);
正常完成因为这个时候p指向是testc b(1,100);

时间: 2024-09-07 03:46:05

C++ RTTI中dynamic_cast的用法的相关文章

linux rtti问题.dynamic_cast失败

问题描述 linux rtti问题.dynamic_cast失败 class base { public: virtual void foo()=0; }; class a:virtual public base { public: virtual void foo(){cout <<"hello"<<endl;} }; 在a和b动态库中都有 以上的定义.在a中实例化了 a 将对象的基类指针(base*)a发送给b 动态库中进行转换 dynamic_cast(o

python中enumerate函数用法实例分析

  本文实例讲述了python中enumerate函数用法.分享给大家供大家参考.具体分析如下: 今日发现一个新函数 enumerate .一般情况下对一个列表或数组既要遍历索引又要遍历元素时,会这样写: ? 1 2 for i in range (0,len(list)): print i ,list[i] 但是这种方法有些累赘,使用内置enumerrate函数会有更加直接,优美的做法,先看看enumerate的定义: ? 1 2 3 4 5 6 7 def enumerate(collect

Excel中sumif函数用法

今天接着给大家来关于Excel中sumif函数用法的操作技巧,那么就有人问了,学会了Excel中sumif函数用法有什么作用呢,不要急,下面就请听小编一一给大家进行详细的讲解: 一.SUMIF函数介绍 SUMIF函数根据指定条件对若干单元格求和,该条件可以是数值.文本或表达式,可以应用在人事.工资和成绩统计中. 二.SUMIF函数用法 sumif函数语法是:SUMIF(range,criteria,sum_range) 第一个参数:Range为条件区域,用于条件判断的单元格区域. 第二个参数:C

error-请教iOS中CMPedometer的用法

问题描述 请教iOS中CMPedometer的用法 10C #import @implementation FirstViewController (void)viewDidLoad { [super viewDidLoad]; [CMPedometer isStepCountingAvailable]; CMPedometer *pedonmeter = [[CMPedometer alloc] init]; [pedonmeter startPedometerUpdatesFromDate:

python中threading超线程用法实例分析

  本文实例讲述了python中threading超线程用法.分享给大家供大家参考.具体分析如下: threading基于Java的线程模型设计.锁(Lock)和条件变量(Condition)在Java中是对象的基本行为(每一个对象都自带了锁和条件变量),而在Python中则是独立的对象.Python Thread提供了Java Thread的行为的子集;没有优先级.线程组,线程也不能被停止.暂停.恢复.中断.Java Thread中的部分被Python实现了的静态方法在threading中以模

python中的闭包用法实例详解

  这篇文章主要介绍了python中的闭包用法,以实例形式详细分析了Python中闭包的概念及相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了python中的闭包用法.分享给大家供大家参考.具体分析如下: 什么是闭包? 简单说,闭包就是根据不同的配置信息得到不同的结果 再来看看专业的解释:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有另

asp中Split的用法示例

示例|split 大家有没有碰到过要想取一字符串里的某些值而无从下手?有没有觉得看书或教材对split的写法糊里糊涂--如果有此疑问的话,请看下面我对例子的解释,相信您会对这个有一定的了解. 例如我想取得一个ftp里的用户名及密码(服务器等)值(用IE当FTP时或从表中取出FTP的值).下面是我的解决思路:设url为收到的URL值,这里指:url=ftp://username:password@server,请注意这句暗墓媛?br>我想大家都看清楚这个URL里的规律了吧,就是各个部分都被"

JSP中日期的用法

js|日期 作者: BUILDER.COM 在开发有关日历的应用程序时,不规则的每月日期数.每周天数和周末的计算一直是个很费脑筋的问题.结果,日期和时间的编程经常令程序员新手畏缩不前.本文将演示在JSP应用程序中日期的用法,为读者完成某些常见任务提供方便的参考. 目的 示例应用程序的目的是: 通过HTML表单把日期参数提交某个JSP页来处理. 接收日期参数并创建Calendar对象. 采用Calendar对象找出提交的日期是一周的第几天以及选中月份里有多少工作日. 用用户易于阅读的显示格式对日期

java中final的用法

许多程序设计语言都有自己的办法告诉编译器某个数据是"常数".常数主要应用于下述两个方面: (1) 编译期常数,它永远不会改变 (2) 在运行期初始化的一个值,我们不希望它发生变化 对于编译期的常数,编译器(程序)可将常数值"封装"到需要的计算过程里.也就是说,计算可在编译期间提前执行,从而节省运行时的一些开销.在Java中,这些形式的常数必须属于基本数据类型(Primitives),而且要用final关键字进行表达.在对这样的一个常数进行定义的时候,必须给出一个值.