0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RTTI和類型轉(zhuǎn)換運(yùn)算符

冬至子 ? 來(lái)源:iDoitnow ? 作者:艱默 ? 2023-07-18 11:23 ? 次閱讀

1. RTTI

RTTI是 運(yùn)行階段類型識(shí)別 (Runtime Type Identification)的簡(jiǎn)稱。該特性是為了程序在運(yùn)行階段確定對(duì)象類型提供一種標(biāo)準(zhǔn)方式。

1.1 RTTI的三個(gè)元素

由于只有包含虛函數(shù)的類層次結(jié)構(gòu),才能將派生類對(duì)象的地址賦給基類指針,因此RTTI只適用包含虛函數(shù)的類。

  • dynamic_cast運(yùn)算符將使用一個(gè)指向基類的指針來(lái)生成一個(gè)指向派生類的指針,否則,該運(yùn)算符返回0—空指針。
  • typeid運(yùn)算符返回一個(gè)指出對(duì)象的類型的值。
  • type_info結(jié)構(gòu)存儲(chǔ)了有關(guān)特定類型的信息

1.1.1 dynamic_cast運(yùn)算符

dynamic_cast運(yùn)算符是RTTI中最常用的組件,其主要的功能是 確定是否可以安全地將對(duì)地址賦給特定類型的指針 ,如果可以則返回該特定類型的指針,如果不可以則返回0(空指針)??梢岳斫鉃?code>dynamic_cast可以用來(lái)類型轉(zhuǎn)換,如果可安全轉(zhuǎn)換,則轉(zhuǎn)換成相應(yīng)的類型指針,否則直接返回0(空指針)。其語(yǔ)法如下:

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;

對(duì)于下面類型的轉(zhuǎn)換:

BaseB* b1 = dynamic_cast

因此針對(duì)該例子,dynamic_cast常用的場(chǎng)景如下:

auto bs = new BaseX;//BaseX為Base、BaseA、BaseB中的任意一種類型,假設(shè)其具體類型只有在程序運(yùn)行過(guò)程中才能確定。
BaseA* pa;
if(pa = dynamic_cast

1.1.2 typeid運(yùn)算符

typeid運(yùn)算符能夠確定兩個(gè)對(duì)象是否為同種類型,其可以接受兩種參數(shù)

  • 類名;
  • 結(jié)果為對(duì)象的表達(dá)式。

其返回一個(gè)type_info對(duì)象的引用,其實(shí)方法如下:

//需要包含頭文件#include< typeinfo >
A* a = new A;//A為一個(gè)類
if(typeid(A) == typeid(*a)){
    std::cout < < "a的類型為A"<

針對(duì)上例,若a是一個(gè)空指針,則typeid(*a)會(huì)引發(fā)bad_typeid異常,該異常類型是從exception類派生出來(lái),也是在typeinfo中生聲明的。

1.1.3. type_info類

type_info類主要存儲(chǔ)了有關(guān)特定類型的信息,其中包含了一個(gè)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)介紹過(guò)其用法,該運(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)化,即改變constvolatile,其語(yǔ)法與dynamic_cast相同:

const_cast < type_name > (expression)

如果類型的其他方面也被修改,則上述類型轉(zhuǎn)換將出錯(cuò),也就是說(shuō)除了constvolatile特征(有或無(wú))可以不同外,type_nameexpression的類型必須相同。假設(shè)AB,則有下面的轉(zhuǎn)換:

A a;
const A* pa = &a;
A* pa1 = const_cast< A* >(pa); //正確
const B* pb = const_cast< const B* >(pa);//錯(cuò)誤

提供該運(yùn)算符的原因是,程序有時(shí)候可能需要一個(gè)這樣的值,它在大多數(shù)的時(shí)候是常量,而有時(shí)候又是可以修改的,在這種情況下,可以將這個(gè)值聲明為const,并在需要修改它的時(shí)候,使用const_cast

2.3 static_cast

static_cast運(yùn)算符與其他類型轉(zhuǎn)換運(yùn)算符的語(yǔ)法一樣:

static_cast < type_name > (expression)

static_castexpression轉(zhuǎn)換為type_name類型,主要用于非多態(tài)類型之間的轉(zhuǎn)換,不提供運(yùn)行時(shí)的檢查來(lái)確保轉(zhuǎn)換的安全性。主要在以下幾種場(chǎng)合中使用:

  • 用于類層次結(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)換是不安全的,也需要程序員來(lái)保證;
  • 用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換 ,如把int轉(zhuǎn)換成char,把int轉(zhuǎn)換成enum等等,這種轉(zhuǎn)換的安全性需要程序員來(lái)保證;
  • 把void指針轉(zhuǎn)換成目標(biāo)類型的指針 ,是極其不安全的,也需要程序員來(lái)保證;

2.4 reinterpret_cast

reinterpret_cast運(yùn)算符與其他類型轉(zhuǎn)換運(yùn)算符的語(yǔ)法一樣:

reinterpret_cast < type_name > (expression)

reinterpret_cast運(yùn)算符用于天生危險(xiǎn)的類型轉(zhuǎn)換,因?yàn)槠湓试S將任何指針類型轉(zhuǎn)換為其它的指針類型。reinterpret_cast運(yùn)算符并不會(huì)改變括號(hào)中運(yùn)算對(duì)象的值,而是對(duì)該對(duì)象從位模式上進(jìn)行重新解釋 。它主要用于將一種數(shù)據(jù)類型從一種類型轉(zhuǎn)換為另一種類型。

例如,它可以將一個(gè)指針轉(zhuǎn)換成一個(gè)整數(shù),也可以將一個(gè)整數(shù)轉(zhuǎn)換成一個(gè)指針,然而,其并不支持所有類型的轉(zhuǎn)換,例如,可以將指針類型轉(zhuǎn)換為足以存儲(chǔ)指針表示的整形,但不能將指針轉(zhuǎn)換為更小的整形或浮點(diǎn)型。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 轉(zhuǎn)換器
    +關(guān)注

    關(guān)注

    27

    文章

    8739

    瀏覽量

    147578
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7522

    瀏覽量

    164096
  • 運(yùn)算符
    +關(guān)注

    關(guān)注

    0

    文章

    172

    瀏覽量

    11094
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C語(yǔ)言運(yùn)算符的使用方法

    詳細(xì)介紹了C語(yǔ)言表達(dá)式、算術(shù)運(yùn)算符、賦值運(yùn)算符、關(guān)系運(yùn)算符、條件結(jié)構(gòu)、邏輯運(yùn)算符、位運(yùn)算符的語(yǔ)法和使用方法,并討論了
    發(fā)表于 11-02 11:30 ?1701次閱讀
    C語(yǔ)言<b class='flag-5'>運(yùn)算符</b>的使用方法

    C語(yǔ)言中基本的運(yùn)算符,表達(dá)示及類型轉(zhuǎn)換

    運(yùn)算符用于向編譯程序說(shuō)明對(duì)數(shù)據(jù)操作的性質(zhì),即操作碼。C 語(yǔ)言提供的運(yùn)算符非常豐富,它們與運(yùn)算量相結(jié)合可形成多種多樣、使用靈活的表達(dá)式。因而為數(shù)據(jù)處理帶來(lái)了極大
    發(fā)表于 11-24 16:10 ?212次下載

    條件運(yùn)算符是什么_條件運(yùn)算符有哪些

    運(yùn)算符優(yōu)先級(jí)高于賦值、逗號(hào)運(yùn)算符,低于其他運(yùn)算符。關(guān)系運(yùn)算實(shí)際上是邏輯比較運(yùn)算,它是邏輯運(yùn)算
    發(fā)表于 11-16 16:02 ?1.1w次閱讀
    條件<b class='flag-5'>運(yùn)算符</b>是什么_條件<b class='flag-5'>運(yùn)算符</b>有哪些

    單目運(yùn)算符是什么_單目運(yùn)算符有哪些

    單目運(yùn)算符是指運(yùn)算所需變量為一個(gè)的運(yùn)算符,又叫一元運(yùn)算符,其中有邏輯非運(yùn)算符:!、按位取反運(yùn)算符
    的頭像 發(fā)表于 02-24 15:42 ?6.1w次閱讀
    單目<b class='flag-5'>運(yùn)算符</b>是什么_單目<b class='flag-5'>運(yùn)算符</b>有哪些

    C++程序設(shè)計(jì)教程之運(yùn)算符重載的詳細(xì)資料說(shuō)明

    ,5. 重載雙目運(yùn)算符,6. 重載單目運(yùn)算符,7. 重載流插入運(yùn)算符和流提取運(yùn)算符,8. 不同類型數(shù)據(jù)間的
    發(fā)表于 03-14 16:04 ?4次下載
    C++程序設(shè)計(jì)教程之<b class='flag-5'>運(yùn)算符</b>重載的詳細(xì)資料說(shuō)明

    C運(yùn)算符的優(yōu)先級(jí)和結(jié)合性詳細(xì)解決

    運(yùn)算符是一種告訴編譯器執(zhí)行特定的數(shù)學(xué)或邏輯操作的符號(hào)。 C語(yǔ)言內(nèi)置了豐富的運(yùn)算符,大體可分為10類:算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位
    的頭像 發(fā)表于 02-22 17:27 ?3271次閱讀

    淺析MySQL中的各類運(yùn)算符

    MySQL支持多種運(yùn)算符,我們?cè)趯?xiě)SQL腳本時(shí)經(jīng)常會(huì)需要用到各種各樣的運(yùn)算符,這些運(yùn)算符可以用來(lái)連接表達(dá)式,進(jìn)而從數(shù)據(jù)庫(kù)中查詢我們需要的結(jié)果集等。這些類型主要包括算術(shù)
    的頭像 發(fā)表于 05-03 17:41 ?2077次閱讀
    淺析MySQL中的各類<b class='flag-5'>運(yùn)算符</b>

    python運(yùn)算符是什么

    python運(yùn)算符 0. 什么是運(yùn)算符? 本章節(jié)主要說(shuō)明Python的運(yùn)算符。舉個(gè)簡(jiǎn)單的例子 4 +5 = 9 。 例子中,4和5被稱為操作數(shù),“+”號(hào)為運(yùn)算符。 Python語(yǔ)言支持
    的頭像 發(fā)表于 02-21 16:44 ?2431次閱讀

    C語(yǔ)言總結(jié)_語(yǔ)句、運(yùn)算符

    當(dāng)前文章復(fù)盤(pán)C語(yǔ)言的: 位運(yùn)算運(yùn)算符、基本運(yùn)算符、數(shù)據(jù)類型、變量、for語(yǔ)句、while語(yǔ)句、goto語(yǔ)句、switch語(yǔ)句、運(yùn)算符優(yōu)先級(jí)強(qiáng)
    的頭像 發(fā)表于 08-14 09:39 ?1032次閱讀

    什么是運(yùn)算符重載

    重載運(yùn)算符是具有特殊名稱的函數(shù),是通過(guò)關(guān)鍵字** operator **后跟運(yùn)算符的符號(hào)來(lái)定義的
    的頭像 發(fā)表于 01-20 15:30 ?2551次閱讀

    條件(三元)運(yùn)算符

    RTL建模中廣泛使用的運(yùn)算符是條件運(yùn)算符,也稱為三元運(yùn)算符,該運(yùn)算符用于在兩個(gè)表達(dá)式之間進(jìn)行選擇——表5-2列出了用于表示條件運(yùn)算符的重點(diǎn)。
    的頭像 發(fā)表于 02-09 15:42 ?1396次閱讀
    條件(三元)<b class='flag-5'>運(yùn)算符</b>

    什么是移位運(yùn)算符

    移位運(yùn)算符將向量的位向右或向左移位指定的次數(shù)。SystemVerilog具有按位和算術(shù)移位運(yùn)算符
    的頭像 發(fā)表于 02-09 15:49 ?1872次閱讀
    什么是移位<b class='flag-5'>運(yùn)算符</b>

    關(guān)系運(yùn)算符與表達(dá)式

    關(guān)系運(yùn)算符的作用就是對(duì)來(lái)倆個(gè)數(shù)值進(jìn)行比較,并且將比較結(jié)果以布爾類型返回。如果關(guān)系運(yùn)算符成立,則返回值為1,布爾類型為真。相反,若關(guān)系運(yùn)算符
    的頭像 發(fā)表于 02-21 15:14 ?1100次閱讀
    關(guān)系<b class='flag-5'>運(yùn)算符</b>與表達(dá)式

    Go語(yǔ)言運(yùn)算符主要包括哪些呢?

    Go語(yǔ)言運(yùn)算符主要包括:算數(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符和其他
    的頭像 發(fā)表于 05-26 15:54 ?894次閱讀
    Go語(yǔ)言<b class='flag-5'>運(yùn)算符</b>主要包括哪些呢?

    邏輯運(yùn)算符兩側(cè)運(yùn)算對(duì)象的數(shù)據(jù)類型

    邏輯運(yùn)算符是編程中常用的運(yùn)算符之一,用于判斷兩個(gè)表達(dá)式之間的關(guān)系,并返回布爾值結(jié)果。在邏輯運(yùn)算中,兩側(cè)運(yùn)算對(duì)象的數(shù)據(jù)類型可以是任意
    的頭像 發(fā)表于 11-30 14:15 ?1883次閱讀