1. 程式人生 > >C++筆記 第六十六課 C++中的型別識別(新內容的最後一課)---狄泰學院

C++筆記 第六十六課 C++中的型別識別(新內容的最後一課)---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux

第六十六課 C++中的型別識別(新內容的最後一課)

1.型別識別

在面向物件中可能出現下面的情況
基類指標指向子類物件
基類引用成為子類物件的別名
在這裡插入圖片描述
靜態型別-變數(物件)自身的型別
動態型別-指標(引用)所指向的物件的實際型別
在這裡插入圖片描述
基類指標是否可以強制型別轉換為子類指標取決於動態型別!

2.C++中如何得到動態型別?

3.動態型別識別

解決方案-利用多型
1.在基類中定義虛擬函式返回具體的型別資訊
2.所有的派生類都必須實現型別相關的虛擬函式
3.每個類中的型別虛擬函式都需要不同的實現

66-1 動態型別識別

#include <iostream>
#include <string>
using namespace std;
class Base//父類
{
public:
    virtual string type()
    {
        return "Base";
    }
};
class Derived : public Base//子類
{
public:
    string type()
    {
        return "Derived";
    }
    
    void printf()
    {
        cout << "I'm a Derived." << endl;
    }
};
class Child : public Base
{
public:
    string type()
    {
        return "Child";
    }
};
void test(Base* b)
{
    /* 危險的轉換方式*/
    // Derived* d = static_cast<Derived*>(b);//強制型別轉換
    
    if( b->type() == "Derived" )
    {
        Derived* d = static_cast<Derived*>(b);//通過虛擬函式返回型別名的方式獲得型別
        
        d->printf();
    }
    
 // cout << dynamic_cast<Derived*>(b) << endl;//有繼承關係的類,有虛擬函式可用dynamic_cast
執行結果
0    //動態型別是base,到dynamic_cast強轉,不成功,B指向父類物件,空指標,返回0
I'm a Derived.   //
0x7fff85f5a8a0  //
0             //同上
}
int main(int argc, char *argv[])
{
    Base b;
    Derived d;
    Child c;
    
    test(&b);
    test(&d);//合法
    test(&c);
    
    return 0;
}
執行結果
I'm a Derived.

多型解決方案的缺陷
必須從基類開始提供型別虛擬函式
所有的派生類都必須重寫型別虛擬函式
每個派生類的型別名必須唯一

4.型別識別關鍵字

C++提供了typeid關鍵字用於獲取型別資訊
typeid關鍵字返回對於引數的型別資訊
typeid返回一個type_info類物件
當typeid的引數為NULL時將丟擲異常
typeid關鍵字的使用
在這裡插入圖片描述

5.動態型別識別

typeid的注意事項
當引數為型別時:返回靜態型別資訊
當引數為變數時:
不存在虛擬函式表-返回靜態型別資訊
存在虛擬函式表-返回動態型別資訊

66-2 typeid型別識別

#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
class Base
{
public:
    virtual ~Base()
    {
    }
};
class Derived : public Base
{
public:
    void printf()
    {
        cout << "I'm a Derived." << endl;
    }
};
void test(Base* b)
{
    const type_info& tb = typeid(*b);
    
    cout << tb.name() << endl;
}
int main(int argc, char *argv[])
{
    int i = 0;
    
    const type_info& tiv = typeid(i); //靜態型別資訊
    const type_info& tii = typeid(int);//得到int型別資訊
    
    cout << (tiv == tii) << endl;
    
    Base b;
    Derived d;
    
    test(&b);
    test(&d);
    
    return 0;
}
執行結果
1
4Base
7Derived

小結
C++中有靜態型別和動態型別的概念
利用多型能夠實現物件的動態型別識別
typeid是專用於型別識別的關鍵字
typeid能夠返回物件的動態型別資訊