今天在看王道宝典的时候看到dynamic_cast ,一直都没用过,也不了解,今天来总结一下。

dynamic_cast 和 static_cast 都可以用来强制转换指针类型,但不同的是dynamic_cast在进行类层次间的下行转换时更加安全

dynamic_cast 运算符可以在执行期决定真正的类型。如果下行转换是安全的(也就是说,如果基类指针或者引用确实指向一个派生类对象),这个运算符会传回转型过的指针。如果下行转换不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。

说了这么多是什么意思呢?总结可以是两句话:

1)在类层次间进行上行转换时,dynamic_cast 和 static_cast 的效果是一样的。

2)在类层次间进行下行转换时,dynamic_cast 具有类型检查的功能,比static_cast 更安全。

例子:下述代码中,若调用函数 func 的实参指向一个B类型的对象,语句1和语句2有什么差别?

  1. #include<iostream>
  2. using namespace std;
  3.  
  4. class B{
  5. public:
  6. B():b(){}
  7. virtual void foo(){};
  8. int b;
  9. };
  10.  
  11. class D:public B{
  12. public:
  13. D():d(){}
  14. int d;
  15. };
  16.  
  17. void func(B *pb){
  18. D *pd1 = static_cast<D *>(pb);//语句1
  19. cout<<pd1->b<<endl;
  20. cout<<pd1->d<<endl;
  21.  
  22. D *pd2 = dynamic_cast<D *>(pb);//语句2
  23. cout<<pd2->b<<endl;
  24. cout<<pd2->d<<endl;
  25. }
  26.  
  27. int main(){
  28. //B* pb = new D;
  29. //func(pb);
  30. B* pb = new B;
  31. func(pb);
  32. return ;
  33. }

一、在上面的代码中,如果pb指向一个D类型的对象,即

  1. B* pb = new D;
  2. func(pb);

输出:

pd1,pd2是一样的,正常得到结果,这两个指针执行D类型的任何操作都是安全的。

二、但是,如果pb指向的是一个B类型的对象,即

  1.    B* pb = new B;
  2. func(pb);

输出:

那么pd1将是一个指向B对象的指针,对它进行D类型的操作将是不安全的(如访问d),输出d的值时,将会是一个垃圾值(此次输出是0),延后了错误的发现;

而pd2将是一个空指针,对空指针进行操作,将会发生异常,从而能够更早地发现错误。

此外,还需注意的一点是 使用dynamic_cast 必须要声明virtual字段,即要有虚函数表!错误输出如下:

这是因为dynamic_cast 运行时类型检查需要类型信息,而这个类型信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表,所以编译错误。而static_cast 则没有这个限制

以上是dynamic_cast 和 static_cast 的区别

 

c++ dynamic_cast 和 static_cast 的区别的更多相关文章

  1. dynamic_cast 和 static_cast 隐式类型转换的区别

    首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion ...

  2. 20140903 dynamic_cast和static的区别 链表的冒泡排序和插入排序

    1.四个类型转换 http://www.cnblogs.com/chio/archive/2007/07/18/822389.html static_cast和dynamic_cast的区别 dyna ...

  3. C++中dynamic_cast与static_cast浅析与实例演示

    1. static_cast 1.1 static_cast语法 static_cast< new_type >(expression) 备注:new_type为目标数据类型,expres ...

  4. C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast

    关于强制类型转换的问题,许多书都讨论过,写的最具体的是C++之父的<C++的设计和演化>. 最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_c ...

  5. C++中reinterpret_cast、const_cast、static_cast、dynamic_cast的作用与区别

    1.reinterpret_cast 作用及原理:将一个类型的指针,转换为另一个类型的指针,这种转换不用修改指针变量值数据存放格式(不改变指针变量值),只需在编译时重新解释指针的类型就可以,当然他也可 ...

  6. static_cast, dynamic_cast, reinterpret_cast, const_cast的区别

    static_cast最像C风格的强制转换,很多时候都需要程序员自身去判断转换是否安全.但是相对C风格的强制转换,在无关类的类指针之间转换上,有安全性的提升. dynamic_cast是运行时的转换吧 ...

  7. C++中的dynamic_cast和static_cast

    代码: #include <cstdio> #include <iostream> using namespace std; class A{ public: virtual ...

  8. C++话题

    1.多态地实现 A:C++中多态的实现原理是怎样的? Q:通过迟邦定技术(late binding)实现. 具体实现原理如下: 1. 基类中函数带virtual关键字,表示该方法为虚函数. 2. 子类 ...

  9. C++笔试题库-------Coding整理

    1. 反转字符串 char* strrev1(const char* str) { int len = strlen(str); ]; char *p = temp + len; *p = '\0'; ...

随机推荐

  1. SecureCRT + Tmux 分屏 高效开发

    最近发现了SecureCRT的一些好玩的功能, 具体如下: 1. 发送消息到所有的终端 首先选中查看-->交互窗口 此时会看到下面出现一个输入窗口 然后, 右击选择"发送交互到所有标签 ...

  2. Linux文本的处理

    Linux最最最最重要的哲学思想就是:一切皆文件.文件以及文件的操作在LInux操作系统中是非常的重要.熟练使用精悍小巧快捷的文本处理方式让效率更高. 一.文件查看命令 less 分页查看 [root ...

  3. byte[] Base64 Stream 之间相互转换

    图片 base64转byte[] /// <summary> /// 保存base64图片,返回阿里云地址 /// </summary> /// <param name= ...

  4. pycaffe︱caffe中fine-tuning模型三重天(函数详解、框架简述)

    本文主要参考caffe官方文档[<Fine-tuning a Pretrained Network for Style Recognition>](http://nbviewer.jupy ...

  5. 第6章 MSI和MSI-X中断机制

    在PCI总线中,所有需要提交中断请求的设备,必须能够通过INTx引脚提交中断请求,而MSI机制是一个可选机制.而在PCIe总线中,PCIe设备必须支持MSI或者MSI-X中断请求机制,而可以不支持IN ...

  6. 理解Android DecorView

    一.DecorView为整个Window界面的最顶层View. 二.DecorView只有一个子元素为LinearLayout.代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域. 三. ...

  7. eclipse中添加Java代码注释模板

    eclipse中添加Java代码注释模板 1.Window->Preference->Java->Code Style->Code Template,进入注释编辑界面 2.文件 ...

  8. Linux集群问题~浅谈

    系统扩展的方式 # scale up 向上扩展 # scale out 向外扩展 集群类型 LB 负载均衡集群 Load Balancing HA 高可用集群 High Availability HP ...

  9. Java 第二章 变量、数据类型和运算符

    第二章      变量.数据类型和运算符 什么是变量: 变量代表一块内存区域,变量类型不一样,这一块内存的大小也不一样. #在编程语言里面,你可以通过定义变量,向内存里添加数据或者修改内存已有的数据. ...

  10. AJAX的简洁写法

    // ajax操作 $('#btn').on('click',function(){ var url = "{:url('confirm')}"; var actual_money ...