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 ) ;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7728585/viewspace-2124368/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7728585/viewspace-2124368/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值