C++ RTTI中dynamic_cast的用法

简介: 我们知道在C++中基类的指针和引用可以指向派生类,因为这是安全的,派生类一定包含了基类 需要的所有的属性和方法,这是向上转换,我们同时还知道虚函数可以随着指针和引用指向的 对象不同而使用不同的方法,这是虚函数的自适应。
我们知道在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 ) ;
相关文章
|
24天前
|
存储 算法 编译器
【C++ TypeName用法 】掌握C++中的TypeName:模板编程的瑞士军刀
【C++ TypeName用法 】掌握C++中的TypeName:模板编程的瑞士军刀
234 0
|
25天前
|
设计模式 存储 缓存
【C++ 基本概念】深入探索C++ RTTI 特性
【C++ 基本概念】深入探索C++ RTTI 特性
61 0
|
28天前
|
存储 JSON 算法
C++ JSON库 nlohmann::basic_json::boolean_t 的用法
C++ JSON库 nlohmann::basic_json::boolean_t 的用法
35 0
|
17天前
|
人工智能 安全 机器人
【C++】const_cast基本用法(详细讲解)
【C++】const_cast基本用法(详细讲解)
|
17天前
|
人工智能 机器人 中间件
【C++】C++回调函数基本用法(详细讲解)
【C++】C++回调函数基本用法(详细讲解)
|
23天前
|
算法 安全 编译器
【C++ 17 新特性 折叠表达式 fold expressions】理解学习 C++ 17 折叠表达式 的用法
【C++ 17 新特性 折叠表达式 fold expressions】理解学习 C++ 17 折叠表达式 的用法
23 1
|
25天前
|
算法 安全 Unix
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
28 0
|
28天前
|
存储 安全 编译器
【C++ 多态 】深入理解C++的运行时类型信息(RTTI):dynamic_cast和typeid的应用与原理
【C++ 多态 】深入理解C++的运行时类型信息(RTTI):dynamic_cast和typeid的应用与原理
49 1
|
28天前
|
存储 JSON 算法
C++ JSON库 nlohmann::basic_json::binary_t的用法
C++ JSON库 nlohmann::basic_json::binary_t的用法
24 0
|
29天前
|
算法 编译器 C++
【C++ 泛型编程 进阶篇】:C++ 元模版编程 typename关键字的多种用法全解析
【C++ 泛型编程 进阶篇】:C++ 元模版编程 typename关键字的多种用法全解析
36 0