理解C++ dynamic_cast

news/2024/5/18 21:52:40

在面向对象程序设计中,有时我们需要在运行时查询一个对象是否能作为某种多态类型使用。与Java的instanceof,以及C#的as、is运算符类似,C++提供了dynamic_cast函数用于动态转型。相比C风格的强制类型转换和C++ reinterpret_cast,dynamic_cast提供了类型安全检查,是一种基于能力查询(Capability Query)的转换,所以在多态类型间进行转换更提倡采用dynamic_cast。本文主要介绍dynamic_cast的意义,用法和注意事项。

 

基本用法

dynamic_cast可以获取目标对象的引用或指针:

T1 obj;

T2* pObj = dynamic_cast<T2*>(&obj);//转换为T2指针,失败返回NULL

T2& refObj = dynamic_cast<T2&>(obj);//转换为T2引用,失败抛出bad_cast异常

 

多态类型

在使用时需要注意:被转换对象obj的类型T1必须是多态类型,即T1必须公有继承自其它类,或者T1拥有虚函数(继承或自定义)。若T1为非多态类型,使用dynamic_cast会报编译错误。下面的例子说明了哪些类属于多态类型,哪些类不是:

//A为非多态类型 

class A{

};

//B为多态类型

class B{ 

    public: virtual ~B(){}

};

//D为多态类型

class D: public A{

};

//E为非多态类型

class E : private A{

};

//F为多态类型

class F : private B{

}

 

横向转型

在多态类型间转换,分为3种类型:

1.子类向基类的向上转型(Up Cast)

2.基类向子类的向下转型(Down Cast)

3.横向转型(Cross Cast)

向上转型是多态的基础,需不要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用即可,当然dynamic_cast也支持向上转型,而其总是肯定成功的。而对于向下转型和横向转型来讲,其实对于dynamic_cast并没有任何区别,它们都属于能力查询。为了理解方便,我们不妨把dynamic_cast视为cross cast:

cross-cast

class Shape {

    public: virtual ~Shape();

    virtual void draw() const = 0;

};

class Rollable {

    public: virtual ~Rollable();

    virtual void roll() = 0;

};

class Circle : public Shape, public Rollable {

    void draw() const;

    void roll();

};

class Square : public Shape {

    void draw() const;

};

 

//横向转型失败

Shape *pShape1 = new Square();

Rollable *pRollable1 = dynamic_cast<Rollable*>(pShape2);//pRollable为NULL

//横向转型成功

Shape *pShape2 = new Circle();

Rollable *pRollable2 = dynamic_cast<Rollable*>(pShape2);//pRollable不为NULL

 

指针比较

接上面的例子,在我的机器上pShape2和pRollable2的值(所指向的地址)分别为:

pShape2: 0x0039A294, pRollable2:0x0039A290

说明dynamic_cast在进行转型的时候对不同多态类型设置了不同的偏移量。接下来的问题是

pRollable2 == pShape2

这个表达式应该返回什么呢?答案是:1,即指针比较相等。也许从C语言转到C++的朋友可能会感到困惑,因为在C语言中指针的比较只是值比较而已。显然,对于多态类型,C++编译器为==运算符做了更多的幕后工作来保证指针比较注重对象的同一性而非指针的值。至于实现细节涉及到C++对象模型,这是我还不甚熟悉的内容,故本文不再深入。


https://dhexx.cn/news/show-2510079.html

相关文章

《树莓派Python编程入门与实战(第2版)》——2.4 LXDE图形界面

本节书摘来自异步社区《树莓派Python编程入门与实战&#xff08;第2版&#xff09;》一书中的第2章&#xff0c;第2.4节&#xff0c;作者[美] Richard Blum Christine Bresnahan&#xff0c;陈晓明 马立新 译&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。…

《Android 平板电脑开发实战详解和典型案例》——2.6节可展开列表—— ExpandableListView...

本节书摘来自异步社区《Android 平板电脑开发实战详解和典型案例》一书中的第2章&#xff0c;第2.6节可展开列表—— ExpandableListView&#xff0c;作者 吴亚峰 , 杜化美 , 索依娜&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看 2.6 可展开列表—— Expand…

DBA避坑宝典:Oracle运维中的那些事儿

对于Oracle运维中的那些事儿&#xff0c;我的最终目的&#xff1a;不是比谁更惨&#xff0c;而是能够从中吸取经验和教训。 从我的理解来看&#xff0c;我会从下面的几个方面来进行说明DBA运维中的一些事儿。 每个部分都是非常关键的&#xff0c;缺一不可&#xff0c;而且每一部…

车联网V2X介绍之:通信芯片

车联网V2X介绍之&#xff1a;通信芯片 参考链接&#xff1a;https://zhuanlan.zhihu.com/p/115276002 目前&#xff0c;我国产业化进程逐步加快&#xff0c;产业链上下游企业已经围绕LTE-V2X形成包括通信芯片、通信模组、终端设备、整车制造、运营服务、测试认证、高精度定位及…

看V2X标准之争,美国/欧洲/日本/中国如何布局车联网?

看V2X标准之争&#xff0c;美国/欧洲/日本/中国如何布局车联网&#xff1f; 参考链接&#xff1a;https://www.ednchina.com/news/20170411V2X.html 中国信息通信研究院副主任汤立波博士在近日“智能交通和安全车联网的未来之路”中分享了车联网的整个产业链&#xff0c;以及…

Nginx HTTPS功能部署实践

本文出处&#xff1a;http://oldboy.blog.51cto.com/2561410/1889346 30.1 文档目的 本文目的提高自己文档的写作能力及排版能力,加强上课所讲的内容得以锻炼也方便自己以后查阅特写此文档。 30.2 文档内容 本章内容包括:单向和双向认证的概念、openssl的介绍、Nginx单向ssl的配…

谈谈车联网--V2X技术

谈谈车联网--V2X技术 参考链接&#xff1a;https://mp.weixin.qq.com/s/-J8QhjURneLaqPhRA4Hmng C-V2X目前产业不断走向成熟&#xff0c;落地场景不断丰富&#xff0c;正处于规模商用的阶段。可以预见&#xff0c;基于蜂窝车联网&#xff08;C-V2X&#xff09;的“聪明的车智慧…

《淘宝店铺 大数据营销+SEO+爆款打造 一册通》一一2.3 用好流量分析,生意突飞猛进...

本节书摘来自异步社区出版社《淘宝店铺 大数据营销SEO爆款打造 一册通》一书中的第2章&#xff0c;第2.3节&#xff0c;作者&#xff1a;葛存山 , 耿寿礼&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.3 用好流量分析&#xff0c;生意突飞猛进 流量分析…

关于Autotalks和V2X介绍

关于Autotalks和V2X介绍 Autotalks是一家来自以色列的初创企业,他们的目的是让汽车能够学会交流,来传递一些之于安全和流通十分重要的信息,也就是V2X。 V2X通讯技术一直被期待用来提高道路安全以及交通效率。通过车辆与交通设施之间的信息传递,以及车辆之间的信息共享,来…

5G关键技术之D2D通信技术

5G关键技术之D2D通信技术 参考链接&#xff1a;5G关键技术之D2D通信技术 (baidu.com) 近年来海量智能终端设备呈现与日俱增的局面&#xff0c;满足用户特定需求的新兴通信业务也处于爆发之势, 移动通信承载的数据流量爆炸式增长和无线频谱资源紧缺的矛盾日益涌现。因此&#…