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

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

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

C++中動(dòng)態(tài)類型的識別

汽車電子技術(shù) ? 來源:嵌入式情報(bào)局 ? 作者:情報(bào)小哥 ? 2023-02-21 10:24 ? 次閱讀

大家好,我是情報(bào)小哥~

1、所要解決的問題

在前面的相同專輯文章中,跟大家介紹過虛函數(shù),其中提到了基類的指針可以指向派生類,同時(shí)基類的引用也可以成為派生類的別名。

比如是非常經(jīng)典的例子:

#include 
using namespace std;

class Parent
{
 public:
  virtual void print(void)
  {
   cout<<"Parent print"<class Child: public Parent
{
 public:
  void print(void)
  {
   cout<<"child print"<void Test1(Parent *ptr)
{
    ptr->print();
}

void Test2(Parent& p)
{
    p.print();
}

int main(int argc, char** argv) {
 
    Child child;
    Parent parent;

    Test1(&child);
    Test1(&parent);
    
    Test2(child);
    Test2(parent);
   
    return 0;
}

這樣其輸出的結(jié)果如下:

圖片

由于存在虛函數(shù)的重寫,所以其函數(shù)調(diào)用都是跟隨傳入的對象類型,這就是多態(tài);當(dāng)然如果此例子中Parent類中的print沒有virtual虛函數(shù)標(biāo)識,則編譯器會認(rèn)為傳入的就是父類指針,從而只會調(diào)用父類的成員。

而從Test1或者Test2對象內(nèi)部看來并不能知道傳參是子類型還是父類型:

void Test1(Parent *ptr)
{
    Child* ptrChild = (Child *)ptr;
 
    ptrChild->dosomething(); //調(diào)用派生類成員
}

如上代碼如果傳入的參數(shù)是子類對象,那么函數(shù)內(nèi)部用子類類型指向該對象是正常運(yùn)行的,但如果此時(shí)傳入的是父類對象,而強(qiáng)制轉(zhuǎn)化為子類指針來使用,則程序就有可能出現(xiàn)未知錯(cuò)誤。

所以這里也引出來兩個(gè)概念:靜態(tài)類型與動(dòng)態(tài)類型

靜態(tài)類型: 即編譯期間所確定的變量類型;

動(dòng)態(tài)類型: 在運(yùn)行過程中指針或者引用所指向?qū)ο蟮膶?shí)際類型。

基于上面的風(fēng)險(xiǎn),我們急需有一種手段來識別變量的動(dòng)態(tài)類型,以進(jìn)行相應(yīng)的處理,我們通常叫其為:RTTI(Run-Time Type Identification,運(yùn)行時(shí)類型識別)

2、進(jìn)行動(dòng)態(tài)類型識別的方法

進(jìn)行動(dòng)態(tài)類型識別的方法挺多的,比如利用多態(tài)對派生類進(jìn)行相應(yīng)ID的標(biāo)識等等,不過推薦還是采用typeid的方式。

typeid關(guān)鍵字能夠獲得任意變量的類型信息,也是C++專門提供用于類型識別的方式。

那么下面我們就用一個(gè)例程在看看typeid如何使用的:

#include 
#include 

using namespace std;

class Parent
{
 public:
  virtual void print(void)
  {
   cout<<"Parent print"<class Child: public Parent
{
 public:
  void print(void)
  {
   cout<<"child print"<void dosomething(void)
  {
   cout<<"dosomething"<void Test1(Parent *ptr)
{

    if( typeid(*ptr) == typeid(Child) ) //具體使用方式 Child
    {
      Child* ptrChild = dynamic_cast(ptr);

        cout<<"**Dynamic Type: "<<"Child"<dosomething();
        
    } 
    else if( typeid(*ptr) == typeid(Parent) ) //Parent
    {
        cout<<"**Dynamic Type: "<<"Parent"<print();
    }

}

void Test2(Parent& p)
{
    if( typeid(p) == typeid(Child) ) //具體使用方式 Child
    {
       Child& ptrChild = (Child&)p;

        cout<<"**Dynamic Type: "<<"Child"<dosomething();
        
    } 
    else if( typeid(p) == typeid(Parent) ) //Parent
    {
        cout<<"**Dynamic Type: "<<"Parent"<print();
    }
}

int main(int argc, char** argv) {
 
    Child child;
    Parent parent;

    Test1(&child);
    Test1(&parent);
    
    cout<Test2(child);
    Test2(parent);
    
    cout<const type_info& tparent = typeid(parent);
    const type_info& tchild = typeid(child);
 
    cout<name()<name()<return 0;
}

其輸出結(jié)果如下:

圖片

結(jié)果看每種指針或者引用的類型均可以動(dòng)態(tài)且正確的獲得識別,挺方便的。

最后有幾點(diǎn)需要注意下:

1、typeid返回值是名為type_info的標(biāo)準(zhǔn)庫類型的對象引用。

2、type_Info的name返回的是一個(gè)字符串,且其類名與實(shí)際程序中類型不一定是一致的,但是肯定是唯一標(biāo)識字符串,通過上面輸出結(jié)果大家也是可以了解到的。

最 后

好了,這里小哥就簡單介紹了C++中動(dòng)態(tài)識別機(jī)制的使用,本系列文章后續(xù)還會更新,記得關(guān)注學(xué)習(xí)哦。

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

    關(guān)注

    1

    文章

    480

    瀏覽量

    70564
  • 虛函數(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    1700
  • 引用
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    7733
收藏 人收藏

    評論

    相關(guān)推薦

    C++打印類型名稱的分析與實(shí)現(xiàn)

    打印類型名稱,聽起來像是一個(gè)很簡單的需求,但在目前的C++當(dāng)中,并非易事。
    發(fā)表于 10-20 14:08 ?1413次閱讀

    labview調(diào)用c++的取地址符對應(yīng)labview什么數(shù)據(jù)類型

    調(diào)用c++動(dòng)態(tài)鏈接庫,有一個(gè)參數(shù)是地址類&data,labview對應(yīng)什么數(shù)據(jù)類型?急急急?。。。。。。。。?!求大神幫忙
    發(fā)表于 08-18 11:47

    關(guān)于C++的函數(shù)重載機(jī)制

    ,而且同類型的同名函數(shù)能夠更好地發(fā)揮多種功能.宏觀體現(xiàn)就是使用一個(gè)函數(shù)名字可以完成各種同類型但是不同細(xì)節(jié)的函數(shù)調(diào)用(例如,參數(shù)的類型不同,或者僅僅是多了一個(gè)控制量參數(shù)......).所以C++
    發(fā)表于 10-01 17:18

    C++的四種類型轉(zhuǎn)換分別是哪些?C++析構(gòu)函數(shù)的作用是什么

    C++的四種類型轉(zhuǎn)換分別是哪些?C++析構(gòu)函數(shù)的作用是什么?在C語言中關(guān)鍵字static主要
    發(fā)表于 12-24 06:57

    C++靜態(tài)分析對泛型構(gòu)件的識別與表示方法

    本文從C++靜態(tài)分析的角度出發(fā),介紹了模板和泛型構(gòu)件技術(shù)、一個(gè)C++靜態(tài)分析器實(shí)現(xiàn)對模板和基本泛型構(gòu)件的分析和識別方法、以及一種基于UML 的泛型構(gòu)件的表示方法。[關(guān)
    發(fā)表于 08-17 11:16 ?14次下載

    人臉識別C/C++源代碼

    人臉識別C/C++源代碼 將生物特征識別應(yīng)用于人臉,實(shí)際上是包含兩個(gè)方面:第一,從圖像或視頻幀檢測人臉,即所謂的“人臉檢測”(face
    發(fā)表于 02-09 16:05 ?184次下載

    C++動(dòng)態(tài)多態(tài)和靜態(tài)多態(tài)

    多態(tài)是 C++ 面向?qū)ο蠹夹g(shù)的核心機(jī)制之一包含靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)它們之間有一定的相似性但是應(yīng)用范圍不同該文論述了這種相似性并重點(diǎn)論述了以模板實(shí)現(xiàn)的靜態(tài)多態(tài)的應(yīng)用范圍
    發(fā)表于 06-29 15:41 ?41次下載
    <b class='flag-5'>C++</b>的<b class='flag-5'>動(dòng)態(tài)</b>多態(tài)和靜態(tài)多態(tài)

    C++語法的外圍基礎(chǔ)

    程序?qū)?nèi)存空間的動(dòng)態(tài)分配的頻繁程度要求簡化語言的相關(guān)語法的格式。C++語法規(guī)定new算符等效于C語言中mal1oc一類的函數(shù)功能;free算符等效于C語言中free一類的函數(shù)功能。其格
    發(fā)表于 03-15 16:55 ?10次下載

    c++ 之布爾類型和引用的學(xué)習(xí)總結(jié)

    c語言里面我們知道是沒有布爾數(shù)據(jù)類型的,而在C++添加了布爾數(shù)據(jù)類型(bool),它的取值是:true或者false(也就是1或者0),
    的頭像 發(fā)表于 12-24 18:03 ?596次閱讀

    現(xiàn)代C++之模板類型推導(dǎo)

    傳統(tǒng)C++,參數(shù)的類型都必須明確定義,這其實(shí)對我們快速進(jìn)行編碼沒有任何幫助,尤其是當(dāng)我們面對一大堆復(fù)雜的模板類型時(shí),必須明確的指出變量的類型
    的頭像 發(fā)表于 03-02 16:18 ?889次閱讀

    C++入門之string

    前一篇文章我們已經(jīng)了解了C++的基本類型,C++還提供了很多抽象數(shù)據(jù)類型,例如字符串string,string包含多個(gè)字符,以及可變長度的
    的頭像 發(fā)表于 03-17 13:58 ?569次閱讀

    C++的引用和指針

    之前的文章我們已經(jīng)介紹了C++的基本類型如int,bool和double等,除了基本類型C++還有一些更復(fù)雜的數(shù)據(jù)
    的頭像 發(fā)表于 03-17 14:00 ?637次閱讀

    CC++編寫環(huán)境下LabVIEW如何調(diào)用動(dòng)態(tài)庫?

    C語言編寫的動(dòng)態(tài)鏈接庫相比,不同的地方在于extern int “C” __declspec(dllexport) add(int x,int y) 這一導(dǎo)出語句,在C代碼
    發(fā)表于 06-11 09:15 ?7778次閱讀
    <b class='flag-5'>C</b>和<b class='flag-5'>C++</b>編寫環(huán)境下LabVIEW如何調(diào)用<b class='flag-5'>動(dòng)態(tài)</b>庫?

    動(dòng)態(tài)數(shù)組和C++ std::vector詳解

    std::vector是C++的默認(rèn)動(dòng)態(tài)數(shù)組,其與array最大的區(qū)別在于vector的數(shù)組是動(dòng)態(tài)的,即其大小可以在運(yùn)行時(shí)更改。std::vector是封裝動(dòng)態(tài)數(shù)組的順序容器,且該容器
    的頭像 發(fā)表于 07-19 11:07 ?974次閱讀

    C++實(shí)現(xiàn)類似instanceof的方法

    函數(shù),可實(shí)際上C++沒有。但是別著急,其實(shí)C++中有兩種簡單的方法可以實(shí)現(xiàn)類似Java的instanceof的功能。 在 C++
    的頭像 發(fā)表于 07-18 10:16 ?589次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>中</b>實(shí)現(xiàn)類似instanceof的方法