dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。

>>>>>>>>>>>编译器的RTTI设置>>>>>>>>>>>

dynamic_cast提供RTTI(Run-Time Type Information),也就是运行时类型识别。它对编译器有要求,需要编译器启动“运行时类型信息”这一选项。当编译器不开启RTTI时,运行含有dynamic_cast操作符的程序时会出现一个警告:

warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“ANIMAL”上;可能导致不可预知的行为

VS2010在默认下是开启RTTI的,也可以自己手动去开启或者关闭,操作如下:

视图->解决方案资源管理器

在打开的解决方案管理器中,对着项目名称右击,选择属性

配置属性-〉C/C++

>>>>>>>>>>>>>步入正题>>>>>>>>>>>>>

  • dynamic_cast主要用于“安全地向下转型”

dynamic_cast用于类继承层次间的指针或引用转换。主要还是用于执行“安全的向下转型(safe downcasting)”,也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。至于“先上转型”(即派生类指针或引用类型转换为其基类类型),本身就是安全的,尽管可以使用dynamic_cast进行转换,但这是没必要的, 普通的转换已经可以达到目的,毕竟使用dynamic_cast是需要开销的。

 1 class Base
 2 {
 3 public:
 4     Base(){};
 5     virtual void Show(){cout<<"This is Base calss";}
 6 };
 7 class Derived:public Base
 8 {
 9 public:
10     Derived(){};
11     void Show(){cout<<"This is Derived class";}
12 };
13 int main()
14 {
15     Base *base ;
16     Derived *der = new Derived;
17     //base = dynamic_cast<Base*>(der); //正确,但不必要。
18     base = der; //先上转换总是安全的
19     base->Show();
20     system("pause");
21 }

  • dynamic_cast与继承层次的指针

对于“向下转型”有两种情况。一种是基类指针所指对象是派生类类型的,这种转换是安全的;另一种是基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做检查,转换失败,返回结果为0;

#include "stdafx.h"
#include<iostream>
using namespace std;class Base
{
public:Base(){};virtual void Show(){cout<<"This is Base calss";}
};
class Derived:public Base
{
public:Derived(){};void Show(){cout<<"This is Derived class";}
};
int main()
{    //这是第一种情况Base* base = new Derived;if(Derived *der= dynamic_cast<Derived*>(base)){cout<<"第一种情况转换成功"<<endl;der->Show();cout<<endl;}//这是第二种情况Base * base1 = new Base;if(Derived *der1 = dynamic_cast<Derived*>(base1)){cout<<"第二种情况转换成功"<<endl;der1->Show();}else {cout<<"第二种情况转换失败"<<endl;}delete(base);delete(base1);system("pause");
}

运行结果:

      

  • dynamic_cast和引用类型

在前面的例子中,使用了dynamic_cast将基类指针转换为派生类指针,也可以使用dynamic_cast将基类引用转换为派生类引用。

同样的,引用的向上转换总是安全的:

    Derived c;Derived & der2= c;Base & base2= dynamic_cast<Base&>(der2);//向上转换,安全base2.Show();

所以,在引用上,dynamic_cast依旧是常用于“安全的向下转型”。与指针一样,引用的向下转型也可以分为两种情况,与指针不同的是,并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常:

int main()
{    //第一种情况,转换成功
    Derived b ;Base &base1= b;Derived &der1 = dynamic_cast<Derived&>(base1);cout<<"第一种情况:";der1.Show();cout<<endl;//第二种情况
    Base a ;Base &base = a ;cout<<"第二种情况:";try{Derived & der = dynamic_cast<Derived&>(base);}catch(bad_cast){cout<<"转化失败,抛出bad_cast异常"<<endl;}system("pause");
}

运行结果:

  • 使用dynamic_cast转换的Base类至少带有一个虚函数

当一个类中拥有至少一个虚函数的时候,编译器会为该类构建出一个虚函数表(virtual method table),虚函数表记录了虚函数的地址。如果该类派生了其他子类,且子类定义并实现了基类的虚函数,那么虚函数表会将该函数指向新的地址。虚表是C++多态实现的一个重要手段,也是dynamic_cast操作符转换能够进行的前提条件。当类没有虚函数表的时候(也即一个虚函数都没有定义),dynamic_cast无法使用RTTI,不能通过编译(个人猜想...有待验证)。

  当然,虚函数表的建立对效率是有一定影响的,构建虚函数表、由表查询函数 都需要时间和空间上的消耗。所以,除了必须声明virtual(对于一个多态基类而言),不要轻易使用virtual函数。对于虚函数的进一步了解,可以查看《Effective C++》

条款07:为多态基类声明virtual析构函数。

转载于:https://www.cnblogs.com/QG-whz/p/4517336.html

C++强制类型转换操作符 dynamic_cast相关推荐

  1. project facets中没有dynamic_C++强制类型转换操作符 dynamic_cast

    dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用. >>>>>>>>>>>编译器的RTTI设 ...

  2. dim private public static_C++ 强制类型转换操作符 static_cast

    (给CPP开发者加星标,提升C/C++技能) 来源:melonstreet https://www.cnblogs.com/QG-whz/p/4509710.html static_cast是一个强制 ...

  3. C++ 强制类型转换操作符(static_cast、dynamic_cast、const_cast和reinterpret_cast)

    C++中的四种操作符形式类型转换 1.static_cast (静态类型转换) 主要使用场景:适用于将void*转换为其他的指针 int a = 100; void* pv = &a; //i ...

  4. C++强制类型转换:dynamic_cast、const_cast 、static_cast、reinterpret_cast

    static_cast(可能不安全):一般.对象指(引)上行/下行转换 dynamic_cast(运行时的安全检查--抛出异常/NULL):对象指(引)上行/下行转换 const_cast:   主要 ...

  5. 显式强制类型转换static_cast, dynamic_cast, const_cast, reinterpret_cast

    显式强制类型转换(cast)包括以下操作符: static_cast,  dynamic_cast, const_cast, reinterpret_cast,对各种显式类型转换解释: static_ ...

  6. 一元操作符、强制类型转换表达式、乘除操作符、加法操作符、移位操作符、关系操作符、判等操作符、位操作符与逻辑操作符、条件与操作符、条件或操作符--运算机制与返回值

    操作符处理及返回值 先遣提示 一元操作符 前缀递增操作符 ++ 前缀递增操作符 - - 一元加号操作符 + 关于一元数值提升或二元数值提升 可以看这篇博客 一元减号操作符 - 这里涉及了 原码,反码, ...

  7. C++ 类型转换 :C语言的类型转换、C++的四种强制类型转换、explicit

    文章目录 C语言中的类型转换 隐式类型转换 显式类型转换 C++ 强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast explici ...

  8. C语言隐式/显式类型转换 | C++四种强制类型转换、类的隐式转换、explicit

    文章目录 C语言类型转换 隐式类型转换 显式类型转换 C++ 强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast 类的隐式类型转换 ...

  9. 第八章 强制类型转换

    c++提供了隐式类型转换,所谓隐式类型转换,是指不需要用户干预,编译器默认进行的类型转换行为(很多时候用户可能都不知道到底进行了哪些转换).例如: int nValue = 8; double dVa ...

最新文章

  1. linux开发神器--Tmux
  2. sqlplus 如何连接到指定数据库,并创建用户与授权
  3. Win32 像素格式描述符学习
  4. sqlite3 改源代码支持上下键查询历史命令
  5. 让 .Net 更方便的导入导出 Excel
  6. 从零开始学JavaWeb
  7. EasyExcel快速上手~读取
  8. 你真的知道什么是多线程吗?为什么要学习多线程?
  9. python selenium截图_python+selenium截图操作样例
  10. linux 中常见的压缩和解压缩的命令
  11. windows下pyhton_vitrualenv虚拟环境pycharm如何创建django项目
  12. 代码下移快捷键_收藏细看!最全面的通达信快捷键一览
  13. verilog实现多周期处理器之——目录及总述
  14. [转]oracle分页用两层循环还是三层循环?
  15. winform定义数据源名称_WinForm中使用CrystalReport水晶报表——基础,分组统计,自定义数据源...
  16. MySQL字符串的拼接方法
  17. 带圆圈的数字和markdown常用表达式记录(持续更新中)
  18. java poi 读合并单元格的内容,poi合并单元格,poi合并单元格并设置内容居中
  19. 【洛谷】P3376 【模板】网络最大流
  20. Android人脸支付功能,android支付宝上刷脸支付的人脸识别技术

热门文章

  1. JAVA 对象分配过程
  2. LINUX的“脏奶牛”
  3. 11.4 iftop:动态显示网络接口流量信息
  4. drf1 rest restful规范
  5. python try catch 能知道是哪一行代码_能导致3.7亿美元损失的异常,到底是怎么回事?...
  6. 1332: 生日日数
  7. 12.04 深圳站 | Serverless Developer Meetup 开放报名
  8. AliGraph:一个工业级的图神经网络平台
  9. 用科幻艺术描绘未知的魅力-环境篇
  10. 《地狱之刃:塞娜的献祭》如何通过人物情感营造恐怖氛围?