1. 程式人生 > >第66課-C++中的型別識別

第66課-C++中的型別識別

一、型別識別

在面向物件中可能出現下面的情況

  • 基類指標指向子類物件
  • 基類引用成為子類物件的別名

這裡寫圖片描述

  • 靜態型別——變數(物件)自身的型別
  • 動態型別——指標(引用)所指向物件的實際型別
void test(Base* b){
  //危險的轉換方式
  Derived* d = static_cast<Derived*>(b);
}

基類指標是否可以強制型別轉換為子類指標取決於動態型別

二、動態型別識別

解決方案——利用多型

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

程式設計實驗:動態型別識別

#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 "Chlid"; } }; 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; } int main(){ Base b; Derived d; Child c; test(&b); test(&d); test(&c); return 0; }

列印結果:

I'm a Derived.

多型解決方案的缺陷:

  • 必須從基類開始提供型別虛擬函式
  • 所有的派生類都必須重寫型別虛擬函式
  • 每個派生類的型別名必須唯一

三、型別識別關鍵字

C++提供了typeid關鍵字用於獲取型別資訊

  • typeid關鍵字返回對應引數的型別資訊
  • typeid返回一個type_info類物件
  • typeid的引數為NULL時將丟擲異常

typeid關鍵字的使用

int i = 0;
const type_info& tiv = typeid(i);
const type_info& tii = typeid(int);

cout << (tiv == tii)<< endl;
//列印結果為1

typeid注意事項

  • 引數為型別時:返回靜態型別資訊
  • 引數為變數時:
    • 不存在虛擬函式表——返回靜態型別資訊
    • 存在虛擬函式表——返回動態型別資訊

程式設計實驗: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 Derive." << endl;
        }
};

void test(Base* b){
    const type_info& tb = typeid(*b);
    cout << tb.name() << endl;
}

int main(){
    int i = 0;
    const type_info& tiv = typeid(i);
    const type_info& tii = typeid(int);

    cout << (tiv == tii) << endl;
    Base b;
    Derived d;
    test(&b);
    test(&d);

    return 0;
} 

列印結果:

1
4Base
7Derived  //因為存在虛擬函式,此時返回動態型別

四、總結

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