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

研究了一波RTTI,你會了嗎

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

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

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

一般在dynamic_cast和typeid中用到,例如父類B的指針轉換子類A的指針,dynamic_cast會判斷B究竟是不是A的父類,如果不是,會返回nullptr,相對于強轉會更加安全。依據什么判斷的呢?就是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; 

結果如下:

  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 

上面的代碼是正常的一段使用多態的代碼,同時也包含了子類指針轉基類指針,基類指針轉子類指針,從輸出結果中可以看到,使用dynamic_cast進行不合理的基類子類指針轉換時,會返回nullptr,而強轉則不會返回nullptr,運行時肯定就會出現奇奇怪怪的錯誤,比較難排查。

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

  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信息,其中包括類的名稱及其基類的信息。此信息用于實現typeid運算符以及dynamic_cast。(大小問題大家可以自己編寫代碼驗證一下)

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

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

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

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

  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() 

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

 

責任編輯:武曉燕 來源: 程序喵大人
相關推薦

2022-04-19 08:28:34

main函數

2022-12-07 10:17:32

WindowsANSI

2021-11-08 12:44:48

AndroidC++內存

2024-01-19 08:25:38

死鎖Java通信

2022-04-01 08:23:17

InputstreString字符串

2024-02-04 00:00:00

Effect數據組件

2023-07-26 13:11:21

ChatGPT平臺工具

2023-01-10 08:43:15

定義DDD架構

2023-08-01 12:51:18

WebGPT機器學習模型

2024-01-02 12:05:26

Java并發編程

2021-01-01 09:03:44

故障HAProxy服務器

2023-03-10 22:08:20

2014-07-17 09:05:29

2023-10-10 11:04:11

Rust難點內存

2024-05-06 00:00:00

InnoDBView隔離

2024-07-31 08:39:45

Git命令暫存區

2022-05-06 08:26:32

JavaSPI機制

2023-01-30 09:01:54

圖表指南圖形化

2022-07-08 09:27:48

CSSIFC模型

2023-12-12 08:02:10

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩成人免费在线视频 | 国产精品伦理一区 | 男女免费在线观看视频 | 国产成人精品视频在线观看 | 亚洲天堂影院 | 国产福利精品一区 | 51ⅴ精品国产91久久久久久 | 成人毛片视频在线播放 | 国产日产精品一区二区三区四区 | 一区精品国产欧美在线 | 欧美国产视频一区二区 | 欧美一区二区在线播放 | 成人毛片视频免费 | 国产欧美一区二区三区久久人妖 | 久久一 | 精品免费国产 | 蜜臀av日日欢夜夜爽一区 | 亚洲精品乱码8久久久久久日本 | 国产成人综合亚洲欧美94在线 | 国产精品久久久久久久久久免费 | 亚洲成人国产精品 | 国产精品1区2区 | 亚洲成人精品 | 国产欧美精品一区二区 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 亚洲啊v在线 | 欧美精品一 | 高清国产午夜精品久久久久久 | 亚洲一区二区三区四区在线观看 | 日韩欧美一区二区三区免费看 | 亚洲精品天堂 | 欧美一级三级在线观看 | 九九热精品视频 | 国产九九精品 | 国产精品av久久久久久久久久 | 日本大片在线播放 | 三级在线观看 | 欧美激情a∨在线视频播放 成人免费共享视频 | 国产美女h视频 | 亚洲欧美激情四射 | 国产视频久久 |