65

关于dynamic_cast

 6 years ago
source link: http://blog.guoyb.com/2018/11/03/dynamic-cast/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

有时候,项目需求紧,时间少,写代码往往就抓起什么用什么,比较少考虑设计的合理性。dynamic_cast就是一例。

dynamic_cast一般用于down cast,即将父类的指针(或引用)转换成子类的指针(或引用),并提供了运行时的类型检查(RTTI功能),转换失败时,会返回一个nullptr(引用则抛出bad cast异常)。

在菱形继承关系中,还可以完成到兄弟类型的转化,不过如果涉及到菱形继承,我觉得还是应该立马审视下当前的类型设计结构,太复杂了,《深入理解C++对象模型》没读过10遍以上,很容易出问题=-=

我遇到的问题比较简单,几个protobuf的消息对象,可以通过一个枚举类型的变量区分。在处理逻辑中需要对它们分别进行处理,但是处理逻辑中,有一大块的逻辑是通用的。

考虑到protobuf的消息类型全部继承自protobuf::Message,于是我将这一块通用逻辑,抽象成了一个共用函数,以protobuf::Message的指针为参数。

在这个共用函数中,又有部分逻辑是针对各个特定的消息MessageA,MessageB……的,于是在这里,我根据上面说到的可以用于区分类型的枚举对象,将Message*指针分别dynamic_cast到MessageA*,MessageB*等,然后进行特殊的逻辑。

但是,dynamic_cast是有性能损失的,毕竟要动态检查类型。有人测算过,dynamic_cast对比static_cast,时延要多4倍。而在我的程序里,消除掉dynamic_cast之后,时延可以缩短40%左右。

其实,大部分的down cast,都可以通过继承、重载来实现。这样就把需要在线做的动态类型判断,放到编译期完成了。

针对我这里的需求,其实完全可以把通用的逻辑,用模板的方式实现,再配合同名不同参函数的重载,分别实现针对子类型特有的逻辑。这样,在编译期,就为每一种类型生成了自己独立的逻辑通路,运行时就可以完全规避掉动态类型转换,从而提高性能。

毕竟,代码里各处xxx_cast<>,看起来还是非常不舒服的,是吧?

据说,C++在设计之初,类型转换中引入static_cast,dynamic_cast,reinterpret_cast这么多难以拼写的cast,就是为了让大家尽量少用……

转载请注明出处: http://blog.guoyb.com/2018/11/03/dynamic_cast/

欢迎使用微信扫描下方二维码,关注我的微信公众号TechTalking,技术·生活·思考:

RZbqqiM.jpg!web

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK