c++类型转换及RTTI

我们都知道C++完全兼容C语言,C语言的转换方式很简单,可以在任意类型之间转换,但这也恰恰是缺点,因为极其不安全,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,但是C这种转换方式不利于我们审查代码,且程序运行时也可能会出bug。

所以C++引入的这几种类型转换可以完美的解决上述问题,不同场景下不同需求使用不同的类型转换方式,同时有利于代码审查。

孙悟空都只有七十二变,不能瞎变,所以c++给类型转换做了限制。

1、static_cast

static_cast <type-name> <expression>

仅当type_name可以被隐式转换为expression所属类型或expression可隐式转换成type_name所属类型时,上述转换才是合法的。

static_cast是用得最多的一类类型转换符,常见的枚举值转成整形,float转整形之类的,都是可以的。

另外,static_cast还可以将派生类指针转换为基类指针,而且一定条件下还能将基类指针转换为派生类指针,且不会报错,只是一些只有派生类才会有的函数、成员变量,转换过来的指针也不会有

Test test;
    TestDerived derived;
    cout << "----------" << endl;

    Test* tp = static_cast<Test*>(&derived);
    tp->func();
    cout << "-----------------" << endl;
    TestDerived* dp = static_cast<TestDerived*>(&test);
    dp->func();
    dp->speak();

//以下是控制台输出
----------
TestDerived func
-----------------
test func

2、dynamic_cast
dynamic_cast运算符的语法和static_cast一样,但它的作用和static_cast略有区别。

kotlin中有个语法叫 is,本人觉得dynamic_cast就是kotlin中的is

dynamic_cast,一般只用于基类和派生类之间的转换,而且只能用于派生类指针转换成基类指针,不能反向转换

    if (Test* tpp = dynamic_cast<Test*>(&derived)) {
        cout << "devived can cast to test" << endl;
    }
    if (TestDerived* dpp = dynamic_cast<TestDerived*>(&test)) {
        cout << "test can cast to TestDerived" << endl;
    }

//输出
devived can cast to test

如代码所示,如果dynamic_cast转换成功,将返回一个指针,如果转换失败,将返回一个空指针。所以代码中的两个if判断,只有一个生效。看这种调用方式,是不是和kotlin中的 is 很相象呢

3、const_cast

const_cast运算符,只用于执行一种用途的类型转换,即改变值为const或volatile。

它一般用于去const运算符。但去运算符之后的效果却是难以预料。

    const int num = 10;
    const int* tempN = const_cast<const int*>(&num);
    cout << "tempn = " << *tempN << endl;
    int* temppp = const_cast<int*>(tempN);
    *temppp = 20;
    cout << "num = " << num << "  tempn = " << *tempN << "  temppp = " << *temppp << endl;

输出:
tempn = 10
num = 10  tempn = 20  temppp = 20

如上述代码所示,num是const类型的整形值,它的值始终为10,无法更改。这种转换慎用

4、reinterpret_cast

没有啥特殊场景运用,类似于c语言中的强制转换,一般用得极少。

5、RTTI

RTTI,运行阶段类型识别的简称。

在多态中,比如上面代码中有基类Test和TestDerived,现在有一个Test指针,但不知道这个指针究竟指向的是基类还是派生类,怎么知道指针是指向的哪种对象呢?

这就是RTTI的工作,在运行时判断类型。目前c++中有3个支持RTTI的元素:

  • dynamic_cast,将一个指向基类的指针来生成一个指向派生类的指针,否则,该运算符将返回空指针
  • typeid,返回一个指针对象类型的值
  • type_info,结构存储了有关特定类型的信息

RTTI场景下,父类必须要有虚函数信息,因为RTTI信息存储在虚函数表中。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • RTTI 是 Run Time Type Information 的缩写,从字面上来理解就是执行时期的类型信息,其...
    程序员杨小哥阅读 317评论 0 0
  • C++是一门弱类型的语言,提供了许多复杂和灵巧类型转换的方式。笔者之前写的Python与Go都是强类型的语言,对这...
    LeeHappen阅读 812评论 0 5
  • 0.目录 隐式转换1.1 数值提升1.2 数值转换1.3 限定性转换 显示转换2.1 C风格转换2.2 stati...
    lllnan阅读 1,561评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,471评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,133评论 4 8