当前位置:首页 > 生活百科

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

栏目:生活百科日期:2025-02-25浏览:0

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++》

“c强制类型转换规则(c语言强制转化的正确使用)” 的相关文章

创业基金怎么申请,免费创业基金申请条件

融资难是众多中小企业都逃不过的一个难题,尤其是在企业发展遇到瓶颈、急需资金时,中小企业很难获得及时的帮助。不过现在不要担心啦,北京市科技型中小企业促进专项围绕我...

万网域名查询网站(申请自己的网址的方法)

推荐在万网购买域名。域名后缀有com/net/org/cn等,请注意com是王道,尽管现在想注册一个好一点的com域名非常难。已有阿里云账号,请先登录,否则注册...

win10怎么设置开始菜单样式(win10开始菜单自定义)

win10系统是目前的主流操作系统,相较于之前的系统有很多使用逻辑和界面UI都有了较大的改变。如今win7系统很快也要失去微软的官方支持了,有部分小伙伴就将自己...

外卖代运营有用吗,外卖代运营公司排行

随着外卖市场的不断扩大,外卖这块蛋糕越滚越大,而期间的竞争更是愈发激烈,而对商家的运营能力也要求越来越高。外卖平台给予了所有入驻者做外卖的机会,但是,许多商家并...

eclipse重置窗口布局全部设置(eclipse页面布局恢复方法

1.eclipse取消默认工作空间的方法选择工具条上的widow–&>preferences–&>General–&>StartupandSh...

哪个银行信用卡额度高好申请,2020年最值得办的四张信用

小白用户首卡,很多卡友会问哪家银行的信用卡额度高??这个问题,金宝来回答你!!一般来说,银行都是根据申请人的申请材料和自己的条件进行综合评估,从而给予透支额度。...

农村做小生意做什么好(农村小本生意项目大全)

生活在农村的我们,疫情之下,只是吃饱了睡,睡好了吃,真的是你想要的生活吗?你是否想过,疫情过后,应该何去何从?难道一直颓废下去吗?我们一直忽略的8个生意,一起来...

qq怎么恢复聊天记录,三大方法找回qq聊天记录

说起QQ聊天,大家可能都不陌生,作为最经典的一款社交软件,它陪伴了我们整个青春。如果自己珍藏多年的聊天记录被误删了,相信很多小伙伴都会感到很痛惜,别担心,今天小...

互联网营销渠道有哪些,网络营销的特点及前景分析

互联网快速发展的今天,可以说每个企业都需要网络推广以及网络营销,那么网络推广网络营销的方法都有哪些呢?主流的网络推广如下:?1、付费推广:(百度推广、360点睛...

4款最舒服的折叠床品牌推荐(午休床折叠床质量排名)

小户型装修最爱的就是折叠床了,可以说是最贴心的居家用品。既能单床,又可以当桌椅。节约空间的同时方便实用。舒适而美丽的折叠床总能为“家”家庭增加无限的温馨。这一分...