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 ) ;
相关文章
|
23天前
|
存储 C++ 容器
【C++】map、set基本用法
本文介绍了C++ STL中的`map`和`set`两种关联容器。`map`用于存储键值对,每个键唯一;而`set`存储唯一元素,不包含值。两者均基于红黑树实现,支持高效的查找、插入和删除操作。文中详细列举了它们的构造方法、迭代器、容量检查、元素修改等常用接口,并简要对比了`map`与`set`的主要差异。此外,还介绍了允许重复元素的`multiset`和`multimap`。
29 3
【C++】map、set基本用法
|
1天前
|
C++
第十三问:C++中静态变量的用法有哪些?
本文介绍了 C++ 中静态变量和函数的用法及原理。静态变量包括函数内的静态局部变量和类中的静态成员变量,前者在函数调用间保持值,后者属于类而非对象。静态函数不能访问非静态成员,但可以通过类名直接调用。静态链接使变量或函数仅在定义文件内可见,避免命名冲突。
9 0
|
1天前
|
存储 安全 编译器
第二问:C++中const用法详解
`const` 是 C++ 中用于定义常量的关键字,主要作用是防止值被修改。它可以修饰变量、指针、函数参数、返回值、类成员等,确保数据的不可变性。`const` 的常见用法包括:
15 0
|
4月前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法
|
4月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
52 0
|
5月前
|
C++
C++ string中的函数和常用用法
C++ 中string中的函数和常用用法
47 4
|
6月前
|
C++
c++语言核心技术要点,《运行时类型识别RTTI》
c++语言核心技术要点,《运行时类型识别RTTI》
58 2
|
6月前
|
存储 C++
C++初阶学习第十一弹——探索STL奥秘(六)——深度刨析list的用法和核心点
C++初阶学习第十一弹——探索STL奥秘(六)——深度刨析list的用法和核心点
56 7
|
6月前
|
存储 人工智能 C++
map容器在C++中的具体用法以及相关注意点
map容器在C++中的具体用法以及相关注意点
62 1
|
7月前
|
存储 C++ 容器
C++标准库容器的基本用法
C++标准库容器的基本用法
59 0