c++ dynamic_cast 和 static_cast 的区别
今天在看王道宝典的时候看到dynamic_cast ,一直都没用过,也不了解,今天来总结一下。
dynamic_cast 和 static_cast 都可以用来强制转换指针类型,但不同的是dynamic_cast在进行类层次间的下行转换时更加安全。
dynamic_cast 运算符可以在执行期决定真正的类型。如果下行转换是安全的(也就是说,如果基类指针或者引用确实指向一个派生类对象),这个运算符会传回转型过的指针。如果下行转换不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。
说了这么多是什么意思呢?总结可以是两句话:
1)在类层次间进行上行转换时,dynamic_cast 和 static_cast 的效果是一样的。
2)在类层次间进行下行转换时,dynamic_cast 具有类型检查的功能,比static_cast 更安全。
例子:下述代码中,若调用函数 func 的实参指向一个B类型的对象,语句1和语句2有什么差别?
#include<iostream>
using namespace std; class B{
public:
B():b(){}
virtual void foo(){};
int b;
}; class D:public B{
public:
D():d(){}
int d;
}; void func(B *pb){
D *pd1 = static_cast<D *>(pb);//语句1
cout<<pd1->b<<endl;
cout<<pd1->d<<endl; D *pd2 = dynamic_cast<D *>(pb);//语句2
cout<<pd2->b<<endl;
cout<<pd2->d<<endl;
} int main(){
//B* pb = new D;
//func(pb);
B* pb = new B;
func(pb);
return ;
}
一、在上面的代码中,如果pb指向一个D类型的对象,即
B* pb = new D;
func(pb);
输出:

pd1,pd2是一样的,正常得到结果,这两个指针执行D类型的任何操作都是安全的。
二、但是,如果pb指向的是一个B类型的对象,即
B* pb = new B;
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 的区别的更多相关文章
- dynamic_cast 和 static_cast 隐式类型转换的区别
首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion ...
- 20140903 dynamic_cast和static的区别 链表的冒泡排序和插入排序
1.四个类型转换 http://www.cnblogs.com/chio/archive/2007/07/18/822389.html static_cast和dynamic_cast的区别 dyna ...
- C++中dynamic_cast与static_cast浅析与实例演示
1. static_cast 1.1 static_cast语法 static_cast< new_type >(expression) 备注:new_type为目标数据类型,expres ...
- C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast
关于强制类型转换的问题,许多书都讨论过,写的最具体的是C++之父的<C++的设计和演化>. 最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_c ...
- C++中reinterpret_cast、const_cast、static_cast、dynamic_cast的作用与区别
1.reinterpret_cast 作用及原理:将一个类型的指针,转换为另一个类型的指针,这种转换不用修改指针变量值数据存放格式(不改变指针变量值),只需在编译时重新解释指针的类型就可以,当然他也可 ...
- static_cast, dynamic_cast, reinterpret_cast, const_cast的区别
static_cast最像C风格的强制转换,很多时候都需要程序员自身去判断转换是否安全.但是相对C风格的强制转换,在无关类的类指针之间转换上,有安全性的提升. dynamic_cast是运行时的转换吧 ...
- C++中的dynamic_cast和static_cast
代码: #include <cstdio> #include <iostream> using namespace std; class A{ public: virtual ...
- C++话题
1.多态地实现 A:C++中多态的实现原理是怎样的? Q:通过迟邦定技术(late binding)实现. 具体实现原理如下: 1. 基类中函数带virtual关键字,表示该方法为虚函数. 2. 子类 ...
- C++笔试题库-------Coding整理
1. 反转字符串 char* strrev1(const char* str) { int len = strlen(str); ]; char *p = temp + len; *p = '\0'; ...
随机推荐
- 关于本地化(localization)
关于本地化(localization) 我们都知道,如果不需要做国际化版本的App.我们只需要在info.plist 里修改CFBundleDisplayName就可以了,其实做国际化也就是在不同的国 ...
- 嵌入式linux------ffmpeg移植 编码H264(am335x编码H264)
[cpp] view plaincopy <pre name="code" class="cpp"><pre name="code& ...
- Hidden Markov Models(HMM) 初理解
1. 一个简单例子
- Caused by: java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be ope
1.错误描述 java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.tes ...
- freemarker写select组件报错总结(一)
1.具体错误如下 六月 25, 2014 11:26:29 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Template pr ...
- TypeError: Error #1034: 强制转换类型失败:无法将 mx.controls::DataGrid@9a7c0a1 转换为 spark.core.IViewport。
1.错误描述 TypeError: Error #1034: 强制转换类型失败:无法将 mx.controls::DataGrid@9aa90a1 转换为 spark.core.IViewport. ...
- flask中jinjia2模板引擎使用详解5
接上文 宏 可以理解为函数,即把一些常用的模板片段做好封装,以便于重用,减少工作量和维护难度. 宏的定义很简单: {%macro xxx()%} ##这里写内容 {%endmacro%} 下面引用 ...
- Java语法 示例
第二章: int:整型 double:双精度浮点型 char:字符型 String:字符串型语法:数据类型 变量名: 如:String name: 变量名=值: 如:name="张三&quo ...
- C#图解教程 第十四章 事件
事件 发布者和订阅者源代码组件概览声明事件订阅事件触发事件标准事件的用法 通过扩展EventArgs来传递数据移除事件处理程序 事件访问器 事件 发布者和订阅者 很多程序都有一个共同的需求,既当一个特 ...
- Spring Boot Actutaur + Telegraf + InFluxDB + Grafana 构建监控平台
完成一套精准,漂亮图形化监控系统从这里开始第一步 Telegraf是收集和报告指标和数据的代理 它是TICK堆栈的一部分,是一个用于收集和报告指标的插件驱动的服务器代理.Telegraf拥有插件或集成 ...