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'; ...
随机推荐
- TCP协议的三次握手和四次分手
HTTP连接 HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用. ...
- V4L2驱动的移植与应用(二)
二.V4L2的应用 下面简单介绍一下V4L2驱动的应用流程. 1. 视频采集的基本流程 一般的,视频采集都有如下流程: 2. 打开视频设备 在V4L2中,视频设备被看做一个文件.使用open函数打 ...
- Android可以拖动位置的ListVeiw
参考网址: 1.https://github.com/bauerca/drag-sort-listview 2.http://www.tuicool.com/articles/jyA3MrU
- Java中用正则表达式判断日期格式是否正确
1.Java中用正则表达式判断日期格式是否正确 DateType.java: /** * @Title:DateType.java * @Package:com.you.dao * @Descript ...
- Java中获取文件路径
Java中获取文件路径 1.实例说明 (1)得到 ClassPath的绝对URI路径 Thread.currentThread().getContextClassLoader().getResourc ...
- MySQL插入数据时插入无效的列
1.错误描述 com.mysql.jdbc.exception:jdbc4.MySQLSyntaxErrorException:Unknown column 'man' in 'field list' ...
- Windows gsl runtime error的解决方案
经过两天多的奋战,终于把GLAD源码集成进来了. 在编译.链接都正确,程序开始跑之后,又出了一个让人很无奈的runtime error, 就在 /* Initialize minimizer */ T ...
- [HDU2296]Ring
vjudge Description For the hope of a forever love, Steven is planning to send a ring to Jane with a ...
- [JSOI2008]球形空间产生器sphere
Sol 设一个dis,就有n+1个方程,消掉dis,就只有n个方程,组成一个方程组,高斯消元就好(建议建立方程时推一下,很简单) # include <bits/stdc++.h> # d ...
- Spring入门看这一篇就够了
前言 前面已经学习了Struts2和Hibernate框架了.接下来学习的是Spring框架...本博文主要是引入Spring框架... Spring介绍 Spring诞生: 创建Spring的目的就 ...