C++ RTTI

RTTI

  • 運行時類型識別,根據基類指針或引用檢索指針或引用所指對象的實際類型函數

  • 要使用RTTI,要求基類中具備虛函數spa

兩種方法支持RTTI:指針

  • typeid操做符code

  • dynamic_cast操做符對象

dynamic_cast

動態類型轉換

當須要經過基類指針或引用調用不是基類組成部分的派生類成員,就須要將基類指針或引用轉換爲派生類的指針或引用;固然也能夠經過虛函數的方式,可是某些狀況下是不可能使用虛函數的,好比靜態成員函數;見下:繼承


/*
 * main.cc
 *
 *  Created on: 2014年1月15日
 *      Author: root
 */

#include <stdio.h>

class A{
public:
    static void print(){ printf("A\n"); }
    virtual ~A(){ ; }
    /* 基類必需要用虛函數才能使用RTTI */
};

class B:public A{
public:
    static void print(){ printf("B\n"); }
    virtual ~B(){ ; }
};

int main(int argc,char *argv[]){
    A *a=new B;

    a->print();

    /* 若是要調用B版本的print;此時不可能經過虛函數
     * 因此必須使用動態類型轉換,即dynamic_cast操做符 */
    /* 此時b的做用域爲if塊與if匹配的else塊中 */
    if(B *b=dynamic_cast<B*>(a))
        b->print();
    else
        a->print();

    delete a;
    return 0;
}


dynamic_cast語法

dynamic_cast<派生類指針或引用>(基類指針或引用),將基類指針或引用轉換爲同一繼承層次中派生類的指針或引用;作用域

轉換失敗

dynamic_cast會進行運行時檢查,若是基類指針或引用所指對象的實際類型不是'<派生類指針或引用>'類型,如:字符串


class A{ virtual ~A(){} };
class B:public A{};
class C:public A{};

int main(int argc,char *argv[]){
    A *a=new B;
    dynamic_cast<C*>(a);
    /* 此時就會轉換失敗 */
    delete a;
    return 0;
}

對於 dynamic_cast<派生類指針>(基類指針):io


  • 轉換失敗的話,返回0;ast

對於 dynamic_cast<派生類引用>(基類引用):

  • 因爲不存在空引用,因此轉換失敗的話,拋出bad_cast異常;

typeid

typeid(表達式),返回type_info類型,type_info類是對錶達式的類型的一個包裝,若是有虛函數支持的話,則會返回表達式的運行時實際類型;type_info支持如下操做:


/* 必須包含 <typeinfo> 頭文件才能使用 */
bool operator==(const type_info &__type);
bool operator!=(const type_info &__type);
/* 判斷兩個類型是否相等 */

const char *name()const;
/* 返回類型的字符串表示 */


/*
 * main.cc
 *
 *  Created on: 2014年1月15日
 *      Author: root
 */

#include <stdio.h>
#include <typeinfo>

class A{
public:
	static void print(){ printf("A\n"); }
	virtual ~A(){ ; }
};

class B:public A{
public:
	static void print(){ printf("B\n"); }
	virtual ~B(){ ; }
};

int main(int argc,char *argv[]){
	B b;
	A *a=&b;
	if(typeid(*a) ==typeid(B) )
		printf("B: %s\n",typeid(*a).name());
	else
		printf("AA\n");

	return 0;
}
相關文章
相關標籤/搜索