成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

研究了一波RTTI,你會了嗎

開發(fā) 前端
RTTI 是 Run Time Type Information 的縮寫,從字面上來理解就是運(yùn)行時期的類型信息,它的主要作用就是動態(tài)判斷運(yùn)行時期的類型。

最近研究了一波RTTI,整理了一下知識點(diǎn),在這里分享一下,下面是目錄:

RTTI 是 Run Time Type Information 的縮寫,從字面上來理解就是運(yùn)行時期的類型信息,它的主要作用就是動態(tài)判斷運(yùn)行時期的類型。

一般在dynamic_cast和typeid中用到,例如父類B的指針轉(zhuǎn)換子類A的指針,dynamic_cast會判斷B究竟是不是A的父類,如果不是,會返回nullptr,相對于強(qiáng)轉(zhuǎn)會更加安全。依據(jù)什么判斷的呢?就是RTTI。

先看下面這段代碼:

  1. #include <iostream> 
  2. using std::cout; 
  3. using std::endl; 
  4. class Base 
  5. public
  6.     int a; 
  7.     int b; 
  8.     Base() 
  9.     { 
  10.         cout << this << " Base \n"
  11.     } 
  12.     virtual void func() 
  13.         cout << this << " hello Base \n"
  14.     }; 
  15.     void basefunc() 
  16.         cout << this << " hello basefunc \n"
  17.     } 
  18. }; 
  19. class BaseBB 
  20. public
  21.     int d; 
  22.     int c; 
  23.     BaseBB() 
  24.     { 
  25.         cout << this << " BaseBB \n"
  26.     } 
  27.     virtual void func() 
  28.         cout << this << " hello BaseBB \n"
  29.     } 
  30. }; 
  31. class Derive : public Base 
  32. public
  33.     Derive() 
  34.     { 
  35.         cout << this << " Derive \n"
  36.     } 
  37.     void func() override 
  38.         cout << this << " hello Derive \n"
  39.     } 
  40. }; 
  41. int main() 
  42.     Derive *d = new Derive; 
  43.     typeid(d); 
  44.     d->func(); 
  45.     Base *b = static_cast<Base *>(d); 
  46.     b->func(); 
  47.     b->basefunc(); 
  48.     Derive *b1 = dynamic_cast<Derive *>(b); 
  49.     Derive *b2 = static_cast<Derive *>(b); 
  50.     b1->func(); 
  51.     b2->func(); 
  52.     BaseBB *b3 = dynamic_cast<BaseBB *>(b); 
  53.     BaseBB *b4 = reinterpret_cast<BaseBB *>(b); 
  54.     cout << d << " " << b << " " << b1 << " " << b2 << " " << b3 << " " << b4 << endl; 
  55.     return 0; 

結(jié)果如下:

  1. clang++ test_rtti.cc -std=c++11;./a.out 
  2.  
  3. 0x7fe80ac05920 Base  
  4. 0x7fe80ac05920 Derive  
  5. 0x7fe80ac05920 hello Derive  
  6. 0x7fe80ac05920 hello Derive  
  7. 0x7fe80ac05920 hello basefunc  
  8. 0x7fe80ac05920 hello Derive  
  9. 0x7fe80ac05920 hello Derive  
  10. 0x7fe80ac05920 0x7fe80ac05920 0x7fe80ac05920 0x7fe80ac05920 0x0 0x7fe80ac05920 

上面的代碼是正常的一段使用多態(tài)的代碼,同時也包含了子類指針轉(zhuǎn)基類指針,基類指針轉(zhuǎn)子類指針,從輸出結(jié)果中可以看到,使用dynamic_cast進(jìn)行不合理的基類子類指針轉(zhuǎn)換時,會返回nullptr,而強(qiáng)轉(zhuǎn)則不會返回nullptr,運(yùn)行時肯定就會出現(xiàn)奇奇怪怪的錯誤,比較難排查。

如果在編譯時加上-fno-rtti會怎么樣?結(jié)果是這樣:

  1. clang++ test_rtti.cc -std=c++11 -fno-rtti 
  2.  
  3. test_rtti.cc:60:5: error: use of typeid requires -frtti 
  4.     typeid(d); 
  5.     ^ 
  6. test_rtti.cc:65:18: error: use of dynamic_cast requires -frtti 
  7.     Derive *b1 = dynamic_cast<Derive *>(b); 
  8.                  ^ 
  9. test_rtti.cc:69:18: error: use of dynamic_cast requires -frtti 
  10.     BaseBB *b3 = dynamic_cast<BaseBB *>(b); 
  11.                  ^ 
  12. 3 errors generated. 

可以看到,加上了-fno-rtti編譯時,使用typeid或dynamic_cast會報錯,即添加-fno-rtti編譯會禁止我們使用dynamic_cast和typeid。那為什么要禁止使用他們呢?

1. RTTI的空間成本非常高:每個帶有vtable(至少一個虛擬方法)的類都將獲得RTTI信息,其中包括類的名稱及其基類的信息。此信息用于實(shí)現(xiàn)typeid運(yùn)算符以及dynamic_cast。(大小問題大家可以自己編寫代碼驗(yàn)證一下)

2. 速度慢,運(yùn)行時多判斷了一層,性能肯定更慢一些。

tips:我這里又將typeid和dynamic_cast去掉重新編譯,結(jié)果表明添加了-fno-rtti,還是可以正常使用多態(tài),所以大家不用擔(dān)心rtti的禁用會影響多態(tài)的使用。

都知道RTTI信息是存在于虛函數(shù)表中,而添加-fno-rtti后代表禁止了RTTI,那虛函數(shù)表中還會有rtti信息嗎?

我這里使用clang的命令查看一下虛函數(shù)表:

  1. clang -Xclang -fdump-vtable-layouts -stdlib=libc++ -fno-rtti -c test_rtti.cc 
  2.  
  3. test_rtti.cc:51:17: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions] 
  4.     void func() override 
  5.                 ^ 
  6. Original map 
  7.  void Derive::func() -> void Base::func() 
  8. Vtable for 'Derive' (3 entries). 
  9.    0 | offset_to_top (0) 
  10.    1 | Derive RTTI 
  11.        -- (Base, 0) vtable address -- 
  12.        -- (Derive, 0) vtable address -- 
  13.    2 | void Derive::func() 
  14.  
  15. VTable indices for 'Derive' (1 entries). 
  16.    0 | void Derive::func() 

通過結(jié)果可以看到,即使添加了-fno-rtti,虛函數(shù)表中還是會存在RTTI指針,但是我查看很多文檔都說rtti會導(dǎo)致可執(zhí)行文件的體積增大一些(畢竟-fno-rtti最大的目的就是為了減小代碼和可執(zhí)行文件的大小),所以我估計(jì)指針指向的塊里面可能什么信息都沒有,具體就不得而知了。

 

責(zé)任編輯:武曉燕 來源: 程序喵大人
相關(guān)推薦

2022-04-19 08:28:34

main函數(shù)

2022-12-07 10:17:32

WindowsANSI

2021-11-08 12:44:48

AndroidC++內(nèi)存

2021-01-01 09:03:44

故障HAProxy服務(wù)器

2024-01-19 08:25:38

死鎖Java通信

2022-04-01 08:23:17

InputstreString字符串

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺工具

2023-01-10 08:43:15

定義DDD架構(gòu)

2023-03-10 22:08:20

2014-07-17 09:05:29

2024-01-02 12:05:26

Java并發(fā)編程

2023-08-01 12:51:18

WebGPT機(jī)器學(xué)習(xí)模型

2023-10-10 11:04:11

Rust難點(diǎn)內(nèi)存

2024-05-06 00:00:00

InnoDBView隔離

2024-07-31 08:39:45

Git命令暫存區(qū)

2022-05-13 08:17:05

HTTPRESTful架構(gòu)

2022-05-06 08:26:32

JavaSPI機(jī)制

2023-01-30 09:01:54

圖表指南圖形化

2024-08-06 09:47:57

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产精品不卡 | 精品www| 日日操日日干 | av一区二区三区在线观看 | 一级片视频免费 | 日韩久久久久久 | 艹逼网 | 亚洲精品一区二区三区在线 | 亚洲人成人一区二区在线观看 | 成人特区 | 中文字幕一区二区三区精彩视频 | 国产高清免费 | 九九九精品视频 | 视频在线观看亚洲 | 国产精品久久久久久久久久久久冷 | 亚洲欧美自拍偷拍视频 | 免费av观看 | 国产亚洲一区二区三区 | 青青操91 | 欧美视频免费在线 | 午夜不卡一区二区 | 日韩av免费在线电影 | 欧美黑人一区二区三区 | 国产一区二区在线免费播放 | 国产成人久久精品一区二区三区 | 欧美一级做性受免费大片免费 | 天天射夜夜操 | 日韩一区二区福利视频 | 97av视频| 伊人春色在线观看 | 亚洲国产成人在线视频 | 国产在线麻豆精品入口 | 国产精品99久久久久久www | 免费在线一区二区 | 欧美久久国产 | 亚洲国产精久久久久久久 | 成年人在线观看 | 国产日韩欧美二区 | 亚洲精品区 | 最新中文在线视频 | 99精品视频在线观看 |