static_cast与dynamic_cast转换

static_cast与dynamic_cast转换  

       

一 C语言中存在着两种类型转换:

隐式转换和显式转换

隐式转换:不同数据类型之间赋值和运算,函数调用传递参数……编译器完成

char ch;
int i = ch;

显示转换:在类型前增加 :(Type)变量 对变量进行的转换。用户显式增加

char *pc = (char*)pb;
void *ps = (void*)pa;


二 C++
中的类型转换

  通过这两种方式,C语言中大部分的类型转换都可以顺利进行。

至于能不能进行转换,转换后的结果如何,编译器不管需要用户自己去控制。

  C++继承了C中的隐式和显式转换的方式。但这种转换并不是安全和严格的,

加上C++本身对象模型的复杂性,C++增加了四个显示转换的关键字。(C++是强类型语言)

static_castdynamic_castconst_staticreinterpret_cast

 

1 static_cast

(1)用于基本的数据类型转换(char,int),及指针之间的转换

复制代码
test_enum type = test_enum_1;

char a ;
int b = static_cast<int>(a);
char c = static_cast<char>(b);
type = static_cast<test_enum>(b);

char* pa = NULL;
int *pb = (int*)pa;
//int *pb = static_cast<int*>(pa); //error
//pa = static_cast<char*>(pb) //error
char *pc = (char*)pb;
//char *pc = static_cast<char*>(pb); //error

void *p = static_cast<void*>(pa);
pb = static_cast<int*>(p);
pc = static_cast<char*>(p);
复制代码

 

(2)类层次中基类与子类成员函数指针的转换

 

复制代码
class A
{

public:
void set(){}
};

class B:public A
{
public:
void set(){}
};

typedef void (A::*PS_MFunc)();   //指向类A的成员函数指针

PS_MFunc func = &A::set;
func = static_cast<PS_MFunc>(&B::set); //基类指向子类成员函数指针,必须进行转换
复制代码


(3)类层次结构中基类与子类指针或引用之间的转换  

   上行转换:子类指针或引用转换成基类表示——安全

  下行转换:基类指针或引用转换成子类表示——危险(没有动态类型检查)

复制代码
class A
{
};
class B:public A
{
};
class C:public A
{
};
class D
{
};

A objA;
B objB;
A* pObjA = new A();
B* pObjB = new B();
C* pObjC = new C();
D* pObjD = new D();

objA = static_cast<A&>(objB); //转换为基类引用
objA = static_cast<A>(objB);
objB = static_cast<B>(objA); //error 不能进行转换

pObjA = pObjB; //right 基类指针指向子类对象
//objB = objA; //error 子类指针指向基类对象
pObjA = static_cast<A*>(pObjB); //right 基类指针指向子类
pObjB = static_cast<B*>(pObjA); //强制转换 OK 基类到子类
//pObjC = static_cast<C*>(pObjB); //error 继承于统一类的派生指针之间转换
//pObjD = static_cast<D*>(pObjC); //error 两个无关联之间转换
复制代码

 

2 dynamic_cast

(1)继承关系的类指针对象或引用之间转换

        

复制代码
class A
{
};
class B:public A
{
};
class C:public A
{
};
class D
{
};

A objA;
B objB;
A* pObjA = new A();
B* pObjB = new B();
C* pObjC = new C();
D* pObjD = new D();
//objA = dynamic_cast<A>(objB); //error 非引用

objA = dynamic_cast<A&>(objB);
//objB = dynamic_cast<B&>(objA); //error A 不是多态类型不能转换 若有虚函数则可以进行转换

pObjA = dynamic_cast<A*>(pObjB);
//pObjB = dynamic_cast<B*>(pObjA); //error A 继承关系 不是多态类型不能转换
//pObjB = dynamic_cast<B*>(pObjC); //error C 兄弟关系 不是多态类型不能转换
//pObjB = dynamic_cast<B*>(pObjD); //error D 没有关系 不是多态类型不能转换
复制代码

 

 

(2)包含有虚函数之间对象指针的转换   

复制代码
class A
{
Public:
Virtual ~A(){}
};
class B:public A
{
};
class C:public A
{
};
class D
{
Public:
Virtual ~D(){}
};
pObjB = dynamic_cast<B*>(pObjA);    // worning 继承关系 父类具有虚函数 多态
pObjB = dynamic_cast<B*>(pObjD); //worning 没有关系 D是多态类型可以转换
//以上结果:pObjB == NULL 此处会发生一个运行时错误
复制代码

         也就是说除了基类指针指向子类对象,可以没有虚函数外,其它要进行dynamic_cast转换必须具有虚函数才行。

那这是为什么呢?下面继续>

 

(3)dynam_cast转换的安全性

         dynamic_cast是动态转换,只有在基类指针转换为子类指针时才有意义。

(子类指针转换为基类指针本来就是可以的:基类指针指向子类对象OK)。

但是基类指针转换为子类指针,并不是每一次都有效:只有基类指针本身指向的是一个派生类的对象,

然后将此基类指针转换为对应的派生类指针才是有效的。这种情况在表面上是无法判定的。此时dynamic就发挥了作用。

情况1: static_cast转换       

复制代码
class A
{
};
class B:public A
{
public:
int m; //B 成员
};

A* pObjA = new A();
B* pObjB = NULL;
pObjB = static_cast<B*>(pObjA); //基类指针转化为子类指针 成功转换
pObjB->m = 10;   //实际中pObj所指向的对象 是A类对象
//上面会发生什么呢,在VC6.0中正常运行。。。?

//如果:

pObjB = dynamic_cast<B*>(pObjA); //error 基类A没有虚函数 不构成多态
复制代码

情况2:     dynamic_cast转换    

复制代码
class A
{
public:
virtual ~A(){} //虚函数 多态
};
class B:public A
{
public:
int m;
};

A* pObjA = new A();
B* pObjB = NULL;
pObjB = dynamic_cast<B*>(pObjA); //编译通过
//实际运行结果:pObjB == NULL // dynamic_cast保证转换无效 返回NULL
复制代码

         dynamic_cast转换不成功,则返回0

4 虚函数对于dynamic_cast转换的作用

  为何使用dynamic_cast转换类指针时,需要虚函数呢。

Dynamic_cast转换是在运行时进行转换,运行时转换就需要知道类对象的信息(继承关系等)。

如何在运行时获取到这个信息——虚函数表。

  C++对象模型中,对象实例最前面的就是虚函数表指针,

通过这个指针可以获取到该类对象的所有虚函数,包括父类的。

因为派生类会继承基类的虚函数表,所以通过这个虚函数表,我们就可以知道该类对象的父类,在转换的时候就可以用来判断对象有无继承关系。

  所以虚函数对于正确的基类指针转换为子类指针是非常重要的。

 

转载于:https://www.cnblogs.com/yuanming/p/7063672.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue使用iview Timeline 时间轴不显示问题

vue Timeline 时间轴不显示渲染的效果 官网代码 <Timeline pending><TimelineItem>发布1.0版本</TimelineItem><TimelineItem>发布2.0版本</TimelineItem><TimelineItem>发布3.0版本</TimelineItem><TimelineItem><a href…

python 重置索引_python pandas 对series和dataframe的重置索引reindex方法

reindex更多的不是修改pandas对象的索引&#xff0c;而只是修改索引的顺序&#xff0c;如果修改的索引不存在就会使用默认的None代替此行。且不会修改原数组&#xff0c;要修改需要使用赋值语句。series.reindex()import pandas as pdimport numpy as npobj pd.Series(range(4…

Java EE 6 Web配置文件。 在云上。 简单。

Java SE还可以。 Java EE是邪恶的。 这就是我一直想的。 好吧&#xff0c;现在不再了。 让我分享我的经验。 几周前&#xff0c;我开始考虑将旧版spring hibernate tomcat应用程序移植到新平台上&#xff1a; SAP NetWeaver云 。 我知道您在极客那里的想法&#xff1a;…

Kubernetes核心概念总结

1、基础架构 1.1 Master Master节点上面主要由四个模块组成&#xff1a;APIServer、scheduler、controller manager、etcd。 APIServer。APIServer负责对外提供RESTful的Kubernetes API服务&#xff0c;它是系统管理指令的统一入口&#xff0c;任何对资源进行增删改查的操作都要…

七、spring boot 1.5.4 集成shiro+cas,实现单点登录和权限控制

1.安装cas-server-3.5.2 官网&#xff1a;https://github.com/apereo/cas/releases/tag/v3.5.2 下载地址&#xff1a;cas-server-3.5.2-release.zip 安装参考文章&#xff1a;http://blog.csdn.net/xuxuchuan/article/details/54924933 注意&#xff1a; 输入 <tomcat_key&g…

php连接mysql数据,php连接mysql数据库

$sql_link mysql_connect("主机名","登入用户名","登入用户名密码");如果连接成功&#xff0c;就会返回一个mysql句柄,可以简单的理解成这个$sql_link 是php跟mysql的一个桥梁&#xff0c;通过该桥梁我们可以进入到mysql。进入到mysql之后&…

CSS-自定义变量

使用背景&#xff1a; 一些常见的例子&#xff1a;为风格统一而使用颜色变量一致的组件属性&#xff08;布局&#xff0c;定位等&#xff09;避免代码冗余*更方便的从CSS向JS传递数据&#xff08;例如媒体断点&#xff09; 为什么使用&#xff1a; 以下几点是未来CSS属性的简短…

url存在宽字节跨站漏洞_利用WebSocket跨站劫持(CSWH)漏洞接管帐户

在一次漏洞悬赏活动中&#xff0c;我发现了一个使用WebSocket连接的应用&#xff0c;所以我检查了WebSocket URL&#xff0c;发现它很容易受到CSWH的攻击(WebSocket跨站劫持)有关CSWH的更多详细信息&#xff0c;可以访问以下链接了解https://www.christian-schneider.net/Cross…

php 数组对比 unset,如何区分PHP中unset,array_splice的区别

1.使用的函数a.函数unset()unset ( mixed $var , mixed $... ? ) : voidunset()销毁指定的变量。b.函数array_slice()array_splice(array,start,length,array)array表示数组。start表示删除元素的开始位置。length表示被移除的元素个数&#xff0c;也是被返回数组的长度。(可…

MapReduce算法–二级排序

我们将继续进行有关实现MapReduce算法的系列文章&#xff0c;该系列可在使用MapReduce进行数据密集型文本处理中找到。 本系列的其他文章&#xff1a; 使用MapReduce进行数据密集型文本处理 使用MapReduce进行数据密集型文本处理-本地聚合第二部分 使用Hadoop计算共现矩阵 …

Redis 字符串(String)

Redis 字符串(String) Redis 字符串数据类型的相关命令用于管理 redis 字符串值&#xff0c;基本语法如下&#xff1a; 语法 redis 127.0.0.1:6379> COMMAND KEY_NAME 实例 redis 127.0.0.1:6379> SET runoobkey redis OK redis 127.0.0.1:6379> GET runoobkey "…

前端基础-CSS的各种选择器的特点以及CSS的三大特性

一、 基本选择器二、 后代选择器、子元素选择器三、 兄弟选择器四、 交集选择器与并集选择器五、 序列选择器六、 属性选择器七、 伪类选择器八、 伪元素选择器九、 CSS三大特性 一、 基本选择器 1、id选择器 #1、作用&#xff1a;根据指定的id名称&#xff0c;在当前界面中找…

Php流式 大文件,如何使用PHP解析XML大文件

如果使用 PHP 解析 XML 的话&#xff0c;那么常见的选择有如下几种&#xff1a;DOM、SimpleXML、XMLReader。如果要解析 XML 大文件的话&#xff0c;那么首先要排除的是 DOM&#xff0c;因为使用 DOM 的话&#xff0c;需要把整个文件全部加载才能解析&#xff0c;效率堪忧&…

python 白盒测试_白盒测试教程 - 颜丽的个人空间 - OSCHINA - 中文开源技术交流社区...

总共贴了39节&#xff0c;后续还有很长&#xff0c;共122节&#xff0c;文章名为‘白盒测试教程’1、白盒测试概念2、测试覆盖标准3、逻辑驱动测试4、基本路径测试白盒测试概念1、白盒测试也称结构测试或逻辑驱动测试&#xff0c;是一种测试用例设计方法&#xff0c;它从程序的…

Oracle 分析函数及常用函数

什么叫分析函数(Analytic function)&#xff1f; Oracle从8.1.6开始提供分析函数&#xff0c;分析函数用于计算基于组的某种聚合值&#xff0c;它和聚合函数的不同之处是 对于每个组返回多行&#xff0c;而聚合函数对于每个组只返回一行。 基本语法 function_name(arg1,arg2,..…

ScanTailor-ScanTailor 强大的多方位的满足处理扫描图片的需求

ScanTailor 强大的多方位的满足处理扫描图片的需求ScanTailor 能做什么&#xff1f;批量或单张或选择区间旋转图片自动切割页面&#xff0c;同时提供手动选项自动识别图像歪斜角度&#xff0c;同时提供手动选项自动识别正文内容裁剪&#xff0c;同时提供手动选项设置正文上下左…

使用JavaCV进行手和手指检测

这篇文章是Andrew Davison博士发布的有关自然用户界面&#xff08;NUI&#xff09;系列的一部分&#xff0c;内容涉及使用JavaCV从网络摄像头视频提要中检测手。 注意&#xff1a;可以从http://fivedots.coe.psu.ac.th/~ad/jg/nui055/下载本章的所有源代码。 第5章的彩色斑点检…

oracle+trace参数设置,Oracle autotrace参数详解

SQL> set autotrace traceonly explainSP2-0613: 无法验证 PLAN_TABLE 格式或实体cuug每周五晚8点都有免费网络课程&#xff0c;如需了解可点击cuug官网。SP2-0611: 启用EXPLAIN报告时出错解决方法&#xff1a;1. 以SYS用户登录CONNECT / as SYSDBA ;1. 创建PLAN_TABL…

git提交代码到码云

日常代码一般提交到github比较多&#xff0c;但我还是钟爱马爸爸&#xff0c;没错就是码云。 码云是中文版的代码托管的网站&#xff0c;不存在打开网速问题&#xff0c;使用也蛮方便的&#xff0c;日常自己保存托管代码已经足够&#xff0c;平时使用git提交代码到码云是非常方…

不能装载文档控件。请在检查浏览器的选项中检查浏览器的安全设置_【2020年网络安全宣传周】如何正确设置浏览器...

李夏是一个公司的职员&#xff0c;一天晚上加班赶制文档&#xff0c;由于要向客户汇报产品情况&#xff0c;需要获取大量网上信息&#xff0c;然而在制作中却发现浏览器的网页打不开了。第二天原计划向客户展示的材料未能完整汇总&#xff0c;客户见面对接效果也打了折扣。在当…