真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

學(xué)習(xí)筆記:C++RTTI(dynamic-創(chuàng)新互聯(lián)

文章目錄
  • 一.dynamic_cast
    • 1.為什么需要dynamic_cast
    • 2.dynamic_cast的使用形式
    • 3. 代碼示例
      • 3.1 類定義
      • 3.2 通過(guò)派生類指針調(diào)用基類的方法
      • 3.3 通過(guò)指向派生類的基類指針調(diào)用派生類A有而派生類B沒有的方法
      • 3.4 引用版本
  • 二. typeid
    • 1.用途
    • 2.用法
    • 3.代碼示例
  • 四.參考文獻(xiàn)

陽(yáng)新ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!一.dynamic_cast 1.為什么需要dynamic_cast
  • 首先看dynamic_cast的定義:dynamic_cast是一個(gè)運(yùn)算符,用于將基類的指針或引用安全地轉(zhuǎn)換成派生類的指針或引用。注意:這里的安全僅針對(duì)轉(zhuǎn)換結(jié)果,而不針對(duì)過(guò)程。如果轉(zhuǎn)換成功的話,后續(xù)使用才是安全的。
  • 從上面的定義中,我們很容易聯(lián)想到另外一種基類指針轉(zhuǎn)換成派生類指針的用法也就是虛函數(shù)。基類定義虛函數(shù),后續(xù)用一個(gè)指向派生類的基類指針調(diào)用該函數(shù),這種場(chǎng)景是絕對(duì)安全的,這種安全由編譯器保證,編譯器將根據(jù)對(duì)象的動(dòng)態(tài)類型自動(dòng)選擇正確的函數(shù)版本。但是如果想執(zhí)行以下兩種操作,編譯器無(wú)法再做安全的保證,這時(shí)候就需要用dynamic_cast做顯示轉(zhuǎn)換了。
    ①通過(guò)派生類指針調(diào)用基類的方法;
    ②通過(guò)指向派生類的基類指針調(diào)用派生類A有而派生類B沒有的方法;
2.dynamic_cast的使用形式
  • dynamic_cast(e)
  • dynamic_cast(e)
  • dynamic_cast(e)
    在上面的所有形式中,e的類型必須符合以下3個(gè)條件中的任意一個(gè):e的類型必須是目標(biāo)type的公有派生類,e的類型是目標(biāo)type的公有基類或者e的類型就是目標(biāo)type的類型,如果符合,則轉(zhuǎn)換可以成功,否則失敗。如果一條dynamic_cast語(yǔ)句的轉(zhuǎn)換目標(biāo)是指針類型并且失敗了,則結(jié)果為0.如果轉(zhuǎn)換目標(biāo)是引用類型并且失敗了,則拋出異常std::bad_cast.
    NOTE:dynamic_cast轉(zhuǎn)換中基類必須包含至少一個(gè)虛方法
3. 代碼示例 3.1 類定義
class Base {public:
    Base() = default;
    ~Base() = default;

    virtual void Hello() {std::cout<< "Hello"<< std::endl;
    }

    void Func() {std::cout<< "Func with Base"<< std::endl;
    }
};

class DervideA:public Base {public:
    DervideA() = default;
    ~DervideA() = default;

    void Hello() override {std::cout<< "Hello A"<< std::endl;
    }

    void doSomething() {std::cout<< "do something"<< std::endl;
        return;
    }

    void Func() {std::cout<< "Func with DervideA"<< std::endl;
    }
};

class DervideB:public Base {public:
    DervideB() = default;
    ~DervideB() = default;

    void Hello() override{std::cout<< "Hello B"<< std::endl;
    }

    void Func() {std::cout<< "Func with DervideB"<< std::endl;
    }
};
3.2 通過(guò)派生類指針調(diào)用基類的方法
int main() {DervideA *pDervideA = new (std::nothrow) DervideA;
    if (pDervideA) {pDervideA->Func();
        //場(chǎng)景一:派生類指針轉(zhuǎn)換為基類指針,使用基類的方法
        if (Base *pBase = dynamic_cast(pDervideA)) {pBase->Func();
        }
    }
    delete pDervideA;

    return 0;
}
  • 運(yùn)行結(jié)果:
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo 
Func with DervideA
Func with Base
3.3 通過(guò)指向派生類的基類指針調(diào)用派生類A有而派生類B沒有的方法
void Hello(Base *pBase) {//基類的虛函數(shù),編譯器保證的安全的保證
    pBase->Hello();
    //場(chǎng)景二:基類指針轉(zhuǎn)換指定的派生類指針
    //doSomething方法僅在DervideA中有,無(wú)法直接通過(guò)pBase使用??梢詫⒒愔羔樛ㄟ^(guò)dynamic_cast轉(zhuǎn)換成DervideA的指針進(jìn)行使用
    //如果pBase是指向DervideB的,則轉(zhuǎn)換失敗
    DervideA *pDervideA = dynamic_cast(pBase);
    if (pDervideA)
        pDervideA->doSomething();
    else
        std::cout<< "dynamic_cast failed!"<< std::endl;
}

int main() {Base *p = new (std::nothrow) DervideA;
    if (p)
        ::Hello(p);
    delete p;

    p = new (std::nothrow) DervideB;
    if (p)
        ::Hello(p);
    delete p;

    return 0;
}
  • 運(yùn)行結(jié)果:
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo 
Hello A
do something
Hello B
dynamic_cast failed!
3.4 引用版本
void Hello(Base& refBase)
{refBase.Hello();
    //場(chǎng)景二:基類引用轉(zhuǎn)換指定的派生類引用
    //doSomething方法僅在DervideA中有,無(wú)法直接使用??梢詫⒒愐猛ㄟ^(guò)dynamic_cast轉(zhuǎn)換成DervideA的引用進(jìn)行使用
    //如果轉(zhuǎn)換失敗,拋出異常std::bad_cast
    try
    {DervideA& refDervideA = dynamic_cast(refBase);
        refDervideA.doSomething();
    }
    catch(const std::exception& e)
    {std::cout<< "dynamic_cast failed!"<< std::endl;
        std::cerr<< e.what()<< '\n';
    }
}

int main()
{Base *p = new (std::nothrow) DervideA;
    if (p)
        ::Hello(*p);
    delete p;

    p = new (std::nothrow) DervideB;
    if (p)
        ::Hello(*p);
    delete p;

    DervideA *pDervideA = new (std::nothrow) DervideA;
    if (pDervideA) {pDervideA->Func();
        //場(chǎng)景一:派生類引用轉(zhuǎn)換為基類引用,使用基類的方法
        try
        {Base& refBase = dynamic_cast(*pDervideA);
            refBase.Func();
        }
        catch(const std::exception& e)
        {std::cout<< "dynamic_cast failed!"<< std::endl;
            std::cerr<< e.what()<< '\n';
        }
    }
}

運(yùn)行結(jié)果:

[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo 
Hello A
do something
Hello B
dynamic_cast failed!
std::bad_cast
Func with DervideA
Func with Base
二. typeid 1.用途
  • 獲取對(duì)象的類型
2.用法
  • typeid的表達(dá)式形式是typeid(e),其中e可以是任意表達(dá)式或者類型的名字。typeid操作的結(jié)果是一個(gè)常量對(duì)象的引用,該對(duì)象的類型是標(biāo)準(zhǔn)庫(kù)類型type_info或者type_info的公有派生類類型,type_info類定義在typeinfo頭文件中。
  • typed運(yùn)算符可以用于任意類型的表達(dá)式,和往常一樣,頂層const被忽略,如果表達(dá)式是一個(gè)引用,則typeid返回該引用所引對(duì)象的類型。不過(guò)當(dāng)typeid作用于數(shù)組或者函數(shù)時(shí),并不會(huì)執(zhí)行向指針的標(biāo)準(zhǔn)類型轉(zhuǎn)換。對(duì)于數(shù)組a執(zhí)行typeid(a),則所得的結(jié)果是數(shù)組類型而非指針類型。
  • 當(dāng)運(yùn)算對(duì)象不屬于類類型或者是一個(gè)不包含任何虛函數(shù)的類時(shí),typeid運(yùn)算符指示的是運(yùn)算對(duì)象的靜態(tài)類型。而當(dāng)運(yùn)算對(duì)象的類包含虛函數(shù)時(shí),typeid的結(jié)果直到運(yùn)行時(shí)才會(huì)求得。
  • NOTE:對(duì)一個(gè)對(duì)象指針做typeid運(yùn)算是無(wú)意義的,得到的結(jié)果是指針類型而非指針指向?qū)ο蟮念愵愋?/li>
3.代碼示例
void typeid_test(Base *pBase)
{//typeid對(duì)象指針無(wú)法獲取指針?biāo)笇?duì)象的類類型
    if (typeid(pBase) == typeid(Base))
        std::cout<< "Base"<< std::endl;
    
    //typeid對(duì)象或其引用得出的結(jié)果才是對(duì)象的類型 
    if (typeid(*pBase) == typeid(DervideA)) {std::cout<< "DervideA"<< std::endl;
    }
    else if (typeid(*pBase) == typeid(DervideB)) {std::cout<< "DervideB"<< std::endl;
    }
}

int main()
{int array[] = {1,2,3};
    //typeid一個(gè)數(shù)組的結(jié)果不是數(shù)組類型的指針
    if (typeid(array) == typeid(int*))
        std::cout<< "type of array is int-pointer!"<< std::endl;
    else
        std::cout<< "type of array is not int-pointer!"<< std::endl;
    
    Base *p = new (std::nothrow) DervideA;
    if (p)
        :: typeid_test(p);
    delete p;

    p = new (std::nothrow) DervideB;
    if (p)
        ::typeid_test(p);
    delete p;

    return 0;
}
  • 運(yùn)行結(jié)果:
[root@VM-8-15-centos c++]# ./../../../bin/RTTI_test_demo
type of array is not int-pointer!
DervideA
DervideB
四.參考文獻(xiàn)

C++ Primer 第五版

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


分享名稱:學(xué)習(xí)筆記:C++RTTI(dynamic-創(chuàng)新互聯(lián)
路徑分享:http://weahome.cn/article/ccpies.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部