《C++ Primer plus》学习笔记之”RTTI”
RTTI是運行階段類型識別的簡稱,它為程序在運行階段確定對象的類型提供了一種標準方式。組要注意的是,他們只適用于包含虛函數的對象。
RTTI主要包含三個元素:dynamic_cast,typeid和typeinfo
(1) dynamic_cast
該操作符將使用一個指向基類的指針來生成一個派生類的指針;如果生成失敗,則返回0—空指針。
dynamic_cast不能回答“指針指向的是哪類對象”,但能回答“是否可以安全地將對象的地址賦給特定的類型的指針”。舉例:
| 1 2 3 4 5 | class Grand{…}; class Superb: public Grand{…}; class Magnificent: public Superb {…}; |
假設有以下指針:
| 1 2 3 4 5 | Grand *pg = new Grand; Grand *ps = new Superb; Grand *pm = new Magnificent; |
對于以下轉換:
| 1 2 3 4 5 | Magnificent *p1 = (Magnificent *) pm;?? //#1 Magnificent *p2 = (Magnificent *) pg;?? //#2 Superb *p1 = (Magnificent *) pm;??? //#3 |
哪些是安全的呢?很明顯,#1和#3是安全的,#2是不安全的,因為派生類中可能存在基類中并沒有的數據成員和函數。
怎樣知道類型轉換是否安全呢?可使用dynamic_cast,表達式為:dynamic_cast<Type *>(pt)
如:
| 1 | Superb *pm = dynamic_cast<Superb *>(pg); |
(2) typeid
返回一個指出對象類型的值。可用于判斷兩個對象是否為同類型。與sizeof類似,可接受兩種參數:類名和結果為對象的表達式。
(3) type_info
typeid返回的是對type_info的引用。type_info重載了==和!=操作符,可使用這些操作符對類型進行比較,例如,如果pg指向的是一個Dog對象,則表達式:
typeid(Dog) == typeid(*pg) 的結果為bool值true。
2. 類型轉換操作符
C語言中能夠的類型轉換操作符過于松散,如:
| 1 2 3 4 5 6 7 8 9 10 11 | struct Data {double Data[200];}; struct Junk{int junk[200]}; Data d={2.5, 3.2,2.1}; char* pch = (char *)(&d); char ch = char (&d); Junk *pj = (Junk*)(&d); |
上述轉換中,哪些有意義?除非不講理,否則任何一種均有意義。
對于這種松散情況,C++更為嚴格地限制允許的類型轉換,并添加了4個類型轉換操作符:dynamic_cast(前面已經介紹),const_cast,static_cast,reinterpret_cast。
(1)const_cast:去掉const和volatile標簽,如:
| 1 2 3 4 5 | const int a = 5; const int* b = const_cast<int *>(&a); *b = 6; //ok!!! |
提供該操作符的原因是,有時候可能需要這樣一個值,他在大部分情況下是常量,而有時又是可以修改的。
(2) static_cast: 使用:static_cast<type_name> (expression);
僅當type_name可被隱式轉換為expression所屬的類型或者expression可被隱式轉換為type_name所屬的類型時,上述轉換才合法。
設High是Low的基類,而Pond是一個無關的類,則:
| 1 2 3 4 5 6 7 8 9 10 11 | High high; Low low; …… High *pb = static_cast<High *>(&low); //valid Low *pl = static_cast<Low *>(&high); //valid Pond *pp = static_cast<Pond*>(&low); //invalid |
static可用將整數轉化為枚舉類型,將枚舉類型轉化為整數類型,將double轉為int,將float轉為long等
(3) reinterpret_cast:用于天生危險的類型轉換,有時程序員必須做一些依賴于實現的,令人生厭的操作。如:
| 1 2 3 4 5 6 7 | struct dat {short a; short b;}; long value=0Xa224b118; dat *pd = reinterpret_cast<dat *>(&value); cout<<pd->a; |
原創文章,轉載請注明:?轉載自董的博客
本文鏈接地址:?http://dongxicheng.org/cpp/cpp-rtti/
總結
以上是生活随笔為你收集整理的《C++ Primer plus》学习笔记之”RTTI”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构之堆Heap
- 下一篇: 数据结构之线段树