文学起点网
当前位置: 首页 文学百科

c强制类型转换规则(c语言强制转化的正确使用)

时间:2023-05-23 作者: 小编 阅读量: 1 栏目名: 文学百科

dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。它对编译器有要求,需要编译器启动“运行时类型信息”这一选项。dynamic_cast与继承层次的指针对于“向下转型”有两种情况。当然,虚函数表的建立对效率是有一定影响的,构建虚函数表、由表查询函数都需要时间和空间上的消耗。所以,除了必须声明virtual,不要轻易使用virtual函数。对于虚函数的进一步了解,可以查看《EffectiveC++》

dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。

>>>>>>>>>>>编译器的RTTI设置>>>>>>>>>>>

dynamic_cast提供RTTI(Run-Time Type Information),也就是运行时类型识别。它对编译器有要求,需要编译器启动“运行时类型信息”这一选项。当编译器不开启RTTI时,运行含有dynamic_cast操作符的程序时会出现一个警告:

warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“ANIMAL”上;可能导致不可预知的行为

VS2010在默认下是开启RTTI的,也可以自己手动去开启或者关闭,操作如下:

视图->解决方案资源管理器
在打开的解决方案管理器中,对着项目名称右击,选择属性
配置属性-〉C/C++

>>>>>>>>>>>>>步入正题>>>>>>>>>>>>>

  • dynamic_cast主要用于“安全地向下转型”

dynamic_cast用于类继承层次间的指针或引用转换。主要还是用于执行“安全的向下转型(safe downcasting)”,也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。至于“先上转型”(即派生类指针或引用类型转换为其基类类型),本身就是安全的,尽管可以使用dynamic_cast进行转换,但这是没必要的, 普通的转换已经可以达到目的,毕竟使用dynamic_cast是需要开销的。

class Base{public:Base(){};virtual void Show(){cout<<"This is Base calss";}};class Derived:public Base{public:Derived(){};void Show(){cout<<"This is Derived class";}};int main(){Base *base ;Derived *der = new Derived;//base = dynamic_cast<Base*>(der); //正确,但不必要。base = der; //先上转换总是安全的base->Show();system("pause");}学习交流群:894479708欢迎所有初学和进阶者一起讨论学习!

dynamic_cast与继承层次的指针

对于“向下转型”有两种情况。一种是基类指针所指对象是派生类类型的,这种转换是安全的;另一种是基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做检查,转换失败,返回结果为0;

#include "stdafx.h"#include<iostream>using namespace std;class Base{public:Base(){};virtual void Show(){cout<<"This is Base calss";}};class Derived:public Base{public:Derived(){};void Show(){cout<<"This is Derived class";}};int main(){//这是第一种情况Base* base = new Derived;if(Derived *der= dynamic_cast<Derived*>(base)){cout<<"第一种情况转换成功"<<endl;der->Show();cout<<endl;}//这是第二种情况Base * base1 = new Base;if(Derived *der1 = dynamic_cast<Derived*>(base1)){cout<<"第二种情况转换成功"<<endl;der1->Show();}else{cout<<"第二种情况转换失败"<<endl;}学习交流群:894479708欢迎所有初学和进阶者一起讨论学习!delete(base);delete(base1);system("pause");}

运行结果:

  • dynamic_cast和引用类型

在前面的例子中,使用了dynamic_cast将基类指针转换为派生类指针,也可以使用dynamic_cast将基类引用转换为派生类引用。

同样的,引用的向上转换总是安全的:

Derived c;Derived & der2= c;Base & base2= dynamic_cast<Base&>(der2);//向上转换,安全base2.Show();

所以,在引用上,dynamic_cast依旧是常用于“安全的向下转型”。与指针一样,引用的向下转型也可以分为两种情况,与指针不同的是,并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常:

int main(){//第一种情况,转换成功Derived b ;Base &base1= b;Derived &der1 = dynamic_cast<Derived&>(base1);cout<<"第一种情况:";der1.Show();cout<<endl;//第二种情况Base a ;Base &base = a ;cout<<"第二种情况:";try{Derived & der = dynamic_cast<Derived&>(base);}catch(bad_cast)学习交流群:894479708欢迎所有初学和进阶者一起讨论学习!{cout<<"转化失败,抛出bad_cast异常"<<endl;}system("pause");}

运行结果:

  • 使用dynamic_cast转换的Base类至少带有一个虚函数

当一个类中拥有至少一个虚函数的时候,编译器会为该类构建出一个虚函数表(virtual method table),虚函数表记录了虚函数的地址。如果该类派生了其他子类,且子类定义并实现了基类的虚函数,那么虚函数表会将该函数指向新的地址。虚表是C++多态实现的一个重要手段,也是dynamic_cast操作符转换能够进行的前提条件。当类没有虚函数表的时候(也即一个虚函数都没有定义),dynamic_cast无法使用RTTI,不能通过编译(个人猜想…有待验证)。

当然,虚函数表的建立对效率是有一定影响的,构建虚函数表、由表查询函数 都需要时间和空间上的消耗。所以,除了必须声明virtual(对于一个多态基类而言),不要轻易使用virtual函数。对于虚函数的进一步了解,可以查看《Effective C++》

    推荐阅读
  • 砂锅炸裂的原因(砂锅炸裂什么原因)

    我们一起去了解并探讨一下这个问题吧!砂锅炸裂的原因砂锅容易烧裂是因为砂锅在加工过程中较易出现缝隙,这些缝隙在加热后易导致爆裂等问题。砂锅的导热性较差,因此使用砂锅时应先放水,再将砂锅移至炉具中。使用砂锅时要轻拿轻放,以免碰撞出裂痕,导致加热时破裂。

  • 支付宝蚂蚁借呗利息高吗(支付宝蚂蚁借呗每个人利率都不同)

    而支付宝不仅仅在手机支付方面做工作,还有能解决燃眉之急的现金借贷服务,那就是蚂蚁借呗。要想降低借呗利率和提升额度,下面几点一定要牢记,不能犯。这一些是有效的反应了一个人的个人资产状况,当然你个人资产越多,支付宝对你开放的权限也会越多,同样借呗花呗的额度也会更高。

  • 新手小白怎么选择缝纫机(如何选购适合自己的缝纫机)

    新手小白怎么选择缝纫机随着国内家用缝纫机市场不断升温,世界缝纫机制造商纷纷推出各自的机电一体化缝纫机机型。除了价格上的考虑,在机器性能上,应多留意。在这一过程中,用户可以从以下五点着重检验机电一体化缝纫机的性能。所以,如发现机器在此方面有不良反应,则不要购买。

  • 崇的组词(崇的组词有哪些)

    我们一起去了解并探讨一下这个问题吧!崇的组词崇的组词有推崇、崇朝、崇仰、崇拜、崇尚等。从天亮到早饭时。有时喻时间短暂,犹言一个早晨。

  • 全自动洗衣机安装教程(全自动洗衣机安装步骤)

    跟着小编一起来看一看吧!全自动洗衣机安装教程水龙头带洗衣机接口,连接不需要钢头直接可以取下来,直接卡入洗衣机龙头的接口即可。不锈钢外圈拧回去一半,钢头上面的四个螺丝分别拧松,不锈钢圈也拧松。直接往水龙头的接口卡住,四个螺丝慢慢同时锁紧,白色部位往上拧紧,将水管另一头的螺纹和洗衣机进水口拧紧。

  • 吃什么养颜抗衰老(四种食物有奇效)

    蓝莓被称为“超级水果”,是含有花青素最多的蔬果,除了抗衰老,还可预防结肠癌、改善视力、消除眼部疲劳。胡萝卜本就有“小人参”之称,紫色的胡萝卜对健康更有益,除可防衰老的功效之外,还可预防心血管疾病和某些癌症。紫色葡萄仅次于蓝莓和紫色胡萝卜的富含花青素水果,所含的类黄酮也是一种强力抗氧化剂,是抗衰老的绝佳食物。

  • 胚根是什么意思(胚根解释)

    以下内容大家不妨参考一二希望能帮到您!胚根是什么意思胚根[pēigēn]:指的是胚的下部未发育的根。它的尖端靠近发芽孔,当种子萌发时,胚根一般是首先突破种皮,发育成幼苗的主根。单子叶植物的胚根在植物长大后,会成为植物的主根,生存期短,入土后不久便停止生长,故无明显的主根。

  • 竹荪的种植方法及种子(竹荪如何种植)

    压块种植的方法主要就是将竹荪菌压成块状,然后放进土中进行栽种,这样栽种的竹荪就比较集中,生长的周期也比较短。

  • 民间借款收息犯法吗(一次借款两头收息)

    在分管副检察长的指导下,两级检察机关随即成立专案组。由两级检察机关成立的专案组进行案情分析。2020年9月,永川区检察院以原审判决确有错误为由,依法提请五分院抗诉。同年10月26日,五分院依法向重庆市第五中级法院提出抗诉。2021年6月,永川区法院采纳了检察机关的抗诉意见,撤销一审判决,作出再审判决。再审判决作出后,双方当事人均未上诉。永川区检察院办案检察官召开案件研讨会。

  • 女人看淡一切的昵称(女人看淡一切的昵称大全)

    以下内容大家不妨参考一二希望能帮到您!女人看淡一切的昵称淡疤花渡空瞳南望拼心愈归蝉夏。*子非鱼致青春半成熟-孤单旅人花不见叶寂寞咖啡看清人心理智去爱泣、芷ㄋ忘掉悲伤忘记过往我长高了心似站台一肩之隔一生足矣#爱人如己﹎忘钓过袪`爱情玩笑吥洅ㄨ错过纯色玫瑰·淡定、情绪淡忘、那伤淡忘回忆﹎