首页 > 其他分享 >static_cast和dynamic_cast详解(转载,不错的文章就转载了,作为收藏吧)

static_cast和dynamic_cast详解(转载,不错的文章就转载了,作为收藏吧)

时间:2022-11-06 18:59:19浏览次数:50  
标签:转换 dynamic cast static 类型 转载 type

派生类不仅有自己的方法和属性,同时它还包括从父类继承来的方法和属性。当我们从派生类向基类转换时,不管用传统的c语言还是c++转换方式都可以百分百转换成功。但是可怕是向下转换类型,也就是我们从基类向派生类转换,当我们采用传统的C语言和c++转换时,就会出现意想不到的情况,因为转换后派生类自己的方法和属性丢失了,一旦我们去调用派生类的方法和属性那就糟糕了,这就是对类继承关系和内存分配理解不清晰导致的。好在c++增加了static_cast和dynamic_cast运用于继承关系类间的强制转化

一、static_cast和dynamic_cast使用方式
static_cast< new_type >(expression)
dynamic_cast< new_type >(expression)
备注:new_type为目标数据类型,expression为原始数据类型变量或者表达式。

二、static_cast详解:
static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性

基本类型数据转换举例如下:

char a = 'a';
int b = static_cast<char>(a);//正确,将char型数据转换成int型数据

double *c = new double;
void *d = static_cast<void*>(c);//正确,将double指针转换成void指针

int e = 10;
const int f = static_cast<const int>(e);//正确,将int型数据转换成const int型数据

const int g = 20;
int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性

类上行和下行转换:

class Base
{};

class Derived : public Base
{}

Base* pB = new Base();
if(Derived* pD = static_cast<Derived*>(pB))
{}//下行转换是不安全的(坚决抵制这种方法)

Derived* pD = new Derived();
if(Base* pB = static_cast<Base*>(pD))
{}//上行转换是安全的

三、dynamic_cast详解:
转换方式:
dynamic_cast< type* >(e)
 type必须是一个类类型且必须是一个有效的指针
dynamic_cast< type& >(e)
type必须是一个类类型且必须是一个左值
dynamic_cast< type&& >(e)
type必须是一个类类型且必须是一个右值

e的类型必须符合以下三个条件中的任何一个:
1、e的类型是目标类型type的公有派生类
2、e的类型是目标type的共有基类
3、e的类型就是目标type的类型。

如果一条dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个std::bad_cast异常(该异常定义在typeinfo标准库头文件中)。e也可以是一个空指针,结果是所需类型的空指针。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换(cross cast)。

在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。dynamic_cast是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。

(1)指针类型
举例,Base为包含至少一个虚函数的基类,Derived是Base的共有派生类,如果有一个指向Base的指针bp,我们可以在运行时将它转换成指向Derived的指针,代码如下:

if(Derived *dp = dynamic_cast<Derived *>(bp)){
//使用dp指向的Derived对象
}
else{
//使用bp指向的Base对象
}

值得注意的是,在上述代码中,if语句中定义了dp,这样做的好处是可以在一个操作中同时完成类型转换和条件检查两项任务。

(2)引用类型

因为不存在所谓空引用,所以引用类型的dynamic_cast转换与指针类型不同,在引用转换失败时,会抛出std::bad_cast异常,该异常定义在头文件typeinfo中。

void f(const Base &b){
try{
const Derived &d = dynamic_cast<const Base &>(b);
//使用b引用的Derived对象
}
catch(std::bad_cast){
//处理类型转换失败的情况
}
}

四、转换注意事项:
尽量少使用转型操作,尤其是dynamic_cast,耗时较高,会导致性能的下降,尽量使用其他方法替代。
————————————————
版权声明:本文为CSDN博主「ShyHerry」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014624623/article/details/79837849

标签:转换,dynamic,cast,static,类型,转载,type
From: https://www.cnblogs.com/zdt168/p/16863348.html

相关文章

  • "xxx cannot be cast to jakarta.servlet.Servlet "报错解决方式
    在做jsp的上机时候同学出现了一个500错误:com.kailong.servlet.ComputeBillcannotbecasttojaka.servlet.Servlet然后因为我用的tomcat是8.xx版本,并没有出现过这个情......
  • 默克尔树特点及优缺点(转载)
    FromURL: ​​https://blog.csdn.net/adwen2009/article/details/102601064​​在区块链中,主要使用Merkle树来进行数据正确性的验证。特点默克尔树是一种树,可以是二叉树,......
  • CH58X/CH57X/V208的Broadcaster(广播者)例程讲解
    在对ble进行应用的时候,每个用户的需求可能不尽相同。这里着重介绍从机Broadcaster例程,只广播不连接。使用该例程时可以在手机使用APP上对Broadcaster进行调试。安卓端在......
  • Android LocalBroadcastManager 使用
    前言LocalBroadcastManager简单使用。1.注册【添加IntentFilter】2.反注册3.发广播publicclassMain2ActivityextendsAppCompatActivity{@Overrideprotect......
  • Delphi XE DataSnap.DSServer[2] TDSServer[2] BroadcastMessage-广播消息
    DelphiXEDataSnap.DSServer[2]TDSServer[2]BroadcastMessage-广播消息向所有客户端回调发送消息。functionTDSServer.BroadcastMessage(constChannelName:string......
  • 转载微信公众号图文
    ​ 官方网站:泽优文档助手 产品交流群:​ 扫码加群:​ 1.将微信公众号文章粘贴到编辑器中 粘贴后的图片显示不允许引用的提示,这里不用管。  ​ ......
  • 如何转载到新浪博客
    ​ 官方网站:泽优文档助手 产品交流群:​ 扫码加群:​ 1.进入文章列表页面,点击需要转载的文章标题​2.选中文章内容,右键点击复制​3.打开新浪博客......
  • 如何转载到网易LOFTER
    ​ 官方网站:泽优文档助手 产品交流群:​ 扫码加群:​ 1.进入文章列表页面,点击需要转载的文章标题​2.选中文章内容,右键点击复制​3.登陆网易LOFTER......
  • 如何转载到CSDN博客
    ​ 官方网站:泽优文档助手 产品交流群:​ 扫码加群:​ 1.进入文章列表页面,点击需要转载的文章标题​2.选中文章内容,右键点击复制​3.登陆CSDN博客,选......
  • STM32禁用JTAG,并使用JTAG引脚为通用IO口(转载)
    STM32禁用JTAG,并使用JTAG引脚为通用IO口两种禁用模式标准库配置:RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF,ENABLE);//......