博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
static_cast与dynamic_cast转换
阅读量:6815 次
发布时间:2019-06-26

本文共 4307 字,大约阅读时间需要 14 分钟。

         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
(a); char c = static_cast
(b); type = static_cast
(b); char* pa = NULL; int *pb = (int*)pa; //int *pb = static_cast
(pa); //error //pa = static_cast
(pb) //error
char *pc = (char*)pb; //char *pc = static_cast
(pb); //error void *p = static_cast
(pa); pb = static_cast
(p); pc = static_cast
(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
(&B::set); //基类指向子类成员函数指针,必须进行转换

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

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

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

2 dynamic_cast

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

        

 

 

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

class A {
Public: Virtual ~A(){} }; class B:public A {
}; class C:public A {
}; class D {
Public: Virtual ~D(){} };
pObjB = dynamic_cast
(pObjA); // worning 继承关系 父类具有虚函数 多态 pObjB = dynamic_cast
(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
(pObjA); //基类指针转化为子类指针 成功转换 pObjB->m = 10;   //实际中pObj所指向的对象 是A类对象 //上面会发生什么呢,在VC6.0中正常运行。。。? //如果: pObjB = dynamic_cast
(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
(pObjA); //编译通过 //实际运行结果:pObjB == NULL // dynamic_cast保证转换无效 返回NULL

         dynamic_cast转换不成功,则返回0

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

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

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

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

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

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

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

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

转载地址:http://ghbzl.baihongyu.com/

你可能感兴趣的文章
kvm.virsh常用命令篇
查看>>
[Hive]Hive使用指南四 客户端导入数据
查看>>
用JQuery给图片添加鼠标移入移出事件
查看>>
IPython4_Notebook
查看>>
rac问题思考总结
查看>>
Android 自定义View总结
查看>>
.NET平台开源项目速览(5)深入使用与扩展SharpConfig组件
查看>>
u-boot-1.3.4 移植到S3C2440
查看>>
HotSpot运行时概览#2
查看>>
Go结构体标签表达式v1.0发布,参数校验杀手锏
查看>>
对react中setState的总结
查看>>
[回炉计划]-实现一个图片预加载
查看>>
正则表达式
查看>>
360前端星计划学习-html
查看>>
专注dApp高效执行和高并发的下一代公有链
查看>>
ONE-sys 整合前后端脚手架 koa2 + pm2 + vue-cli3.0 + element
查看>>
携带更方便功能全 iPone与Apple Watch球形尿袋
查看>>
行为型模式:策略模式
查看>>
实现批量数据增强 | keras ImageDataGenerator使用
查看>>
太忙女友消息未及时回复,分手吗?python微信自动消息帮你谈恋爱
查看>>