1. RTTI
RTTI是 運(yùn)行階段類型識別 (Runtime Type Identification)的簡稱。該特性是為了程序在運(yùn)行階段確定對象類型提供一種標(biāo)準(zhǔn)方式。
1.1 RTTI的三個元素
由于只有包含虛函數(shù)的類層次結(jié)構(gòu),才能將派生類對象的地址賦給基類指針,因此RTTI只適用包含虛函數(shù)的類。
dynamic_cast
運(yùn)算符將使用一個指向基類的指針來生成一個指向派生類的指針,否則,該運(yùn)算符返回0—空指針。typeid
運(yùn)算符返回一個指出對象的類型的值。type_info
結(jié)構(gòu)存儲了有關(guān)特定類型的信息。
1.1.1 dynamic_cast運(yùn)算符
dynamic_cast
運(yùn)算符是RTTI中最常用的組件,其主要的功能是 確定是否可以安全地將對地址賦給特定類型的指針 ,如果可以則返回該特定類型的指針,如果不可以則返回0(空指針)。可以理解為dynamic_cast
可以用來類型轉(zhuǎn)換,如果可安全轉(zhuǎn)換,則轉(zhuǎn)換成相應(yīng)的類型指針,否則直接返回0(空指針)。其語法如下:
dynamic_cast< type_name > (expression)
例如下面的例子:
class Base{
private:
double val;
public:
Base(double a = 0):val(a){}
virtial void show(){std::cout< "Base show!"< < std::endl();}
}
class BaseA:public: Base{
BaseA(double a = 0):Base(a){}
virtual void show(){std::cout < "BaseA show!"<
假設(shè)有下面的指針:
Base* bs = new Base;
Base* ba = new BaseA;
Base* bb = new BaseB;
對于下面類型的轉(zhuǎn)換:
BaseB* b1 = dynamic_cast
因此針對該例子,dynamic_cast
常用的場景如下:
auto bs = new BaseX;//BaseX為Base、BaseA、BaseB中的任意一種類型,假設(shè)其具體類型只有在程序運(yùn)行過程中才能確定。
BaseA* pa;
if(pa = dynamic_cast
1.1.2 typeid運(yùn)算符
typeid
運(yùn)算符能夠確定兩個對象是否為同種類型,其可以接受兩種參數(shù):
- 類名;
- 結(jié)果為對象的表達(dá)式。
其返回一個type_info
對象的引用,其實方法如下:
//需要包含頭文件#include< typeinfo >
A* a = new A;//A為一個類
if(typeid(A) == typeid(*a)){
std::cout < < "a的類型為A"<
針對上例,若a
是一個空指針,則typeid(*a)
會引發(fā)bad_typeid
異常,該異常類型是從exception
類派生出來,也是在typeinfo
中生聲明的。
1.1.3. type_info類
type_info
類主要存儲了有關(guān)特定類型的信息,其中包含了一個name()
成員,該成員函數(shù)主要用于調(diào)試,其需要與typeid
搭配使用,使用方法如下:
//class A;
A* a = new A;
std::cout< typeid(*a).name()<
2. 類型轉(zhuǎn)換運(yùn)算符
2.1 dynamic_cast
前面已經(jīng)介紹過其用法,該運(yùn)算符的主要用途是,使得 能夠在類層次結(jié)構(gòu)中進(jìn)行向上轉(zhuǎn)換 (即派生類到基類的轉(zhuǎn)換,由于該轉(zhuǎn)換是is-a的關(guān)系,所以該轉(zhuǎn)換是安全的),而不允許其他的轉(zhuǎn)換。
2.2 const_cast
const_cast
運(yùn)算符用于執(zhí)行只有一種用途的類型轉(zhuǎn)化,即改變const
或volatile
,其語法與dynamic_cast
相同:
const_cast < type_name > (expression)
如果類型的其他方面也被修改,則上述類型轉(zhuǎn)換將出錯,也就是說除了const
或volatile
特征(有或無)可以不同外,type_name
和expression
的類型必須相同。假設(shè)A
和B
,則有下面的轉(zhuǎn)換:
A a;
const A* pa = &a;
A* pa1 = const_cast< A* >(pa); //正確
const B* pb = const_cast< const B* >(pa);//錯誤
提供該運(yùn)算符的原因是,程序有時候可能需要一個這樣的值,它在大多數(shù)的時候是常量,而有時候又是可以修改的,在這種情況下,可以將這個值聲明為const
,并在需要修改它的時候,使用const_cast
。
2.3 static_cast
static_cast
運(yùn)算符與其他類型轉(zhuǎn)換運(yùn)算符的語法一樣:
static_cast < type_name > (expression)
static_cast
將expression
轉(zhuǎn)換為type_name
類型,主要用于非多態(tài)類型之間的轉(zhuǎn)換,不提供運(yùn)行時的檢查來確保轉(zhuǎn)換的安全性。主要在以下幾種場合中使用:
- 用于類層次結(jié)構(gòu)中 ,基類和子類之間指針和引用的轉(zhuǎn)換;當(dāng)進(jìn)行上行轉(zhuǎn)換(把派生類的指針或引用轉(zhuǎn)換成基類表示),這種轉(zhuǎn)換是安全的;當(dāng)進(jìn)行下行轉(zhuǎn)換(把基類的指針或引用轉(zhuǎn)換成派生類表示),這種轉(zhuǎn)換是不安全的,也需要程序員來保證;
- 用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換 ,如把
int
轉(zhuǎn)換成char
,把int
轉(zhuǎn)換成enum
等等,這種轉(zhuǎn)換的安全性需要程序員來保證; - 把void指針轉(zhuǎn)換成目標(biāo)類型的指針 ,是極其不安全的,也需要程序員來保證;
2.4 reinterpret_cast
reinterpret_cast
運(yùn)算符與其他類型轉(zhuǎn)換運(yùn)算符的語法一樣:
reinterpret_cast < type_name > (expression)
reinterpret_cast
運(yùn)算符用于天生危險的類型轉(zhuǎn)換,因為其允許將任何指針類型轉(zhuǎn)換為其它的指針類型。reinterpret_cast
運(yùn)算符并不會改變括號中運(yùn)算對象的值,而是對該對象從位模式上進(jìn)行重新解釋 。它主要用于將一種數(shù)據(jù)類型從一種類型轉(zhuǎn)換為另一種類型。
例如,它可以將一個指針轉(zhuǎn)換成一個整數(shù),也可以將一個整數(shù)轉(zhuǎn)換成一個指針,然而,其并不支持所有類型的轉(zhuǎn)換,例如,可以將指針類型轉(zhuǎn)換為足以存儲指針表示的整形,但不能將指針轉(zhuǎn)換為更小的整形或浮點型。
-
轉(zhuǎn)換器
+關(guān)注
關(guān)注
27文章
8602瀏覽量
146714 -
存儲器
+關(guān)注
關(guān)注
38文章
7434瀏覽量
163519 -
運(yùn)算符
+關(guān)注
關(guān)注
0文章
171瀏覽量
11051
發(fā)布評論請先 登錄
相關(guān)推薦
評論