C++中的類型識別





一、C++中類型識別ios


(1)在面向對象中可能出現下面的狀況ide


@1:基類指針指向子類對象 Base *p = new child();函數

@2:基類引用成爲子類對象的別名 Base& r = *p;spa


--上面的base是基類,child是這個基類的子類,第一種狀況,因爲賦值兼容性的存在,父類指針是能夠指向子類對象的,可是咱們沒法經過父類指針來知道當前指針指向的是不是子類對象。指針


--可是這時咱們能夠說,指針p的靜態類型是Base*(指針指望的類型),指針p的動態類型是child(由於這時指針p指向的類型不是自己指針p所指望的類型,因此child叫指針p的動態類型)對象


--第二種狀況,Base&是r的靜態類型,由於r這個引用指望獲得的類型是Base這個父類,可是因爲賦值兼容性原則,此時r成爲了子類child所在堆空間的別名了,引用自己也沒有辦法肯定引用的到字符串


--底是父類對象仍是子類對象。因此child這個類型此時也是引用r的動態類型(由於和r自己想引用的類型不一樣)。string


(2)靜態類型:變量(對象)自己的類型叫作靜態類型。it


(3)動態類型:指針(引用)所指向對象的實際類型。io


void test(Base *b)

{

child *d = static_cast<child*>(b); //危險的轉換方式,若是b指針指向的子類對象,那就是徹底能夠的。

}


基類指針是否能夠強制類型轉換爲子類指針取決於動態類型。


二、C++中如何獲得對象的動態類型?


(1)解決方案1:利用多態


@1:在基類中定義虛函數返回具體的類型信息(返回字符串,字符串來表示當前的類型信息)

@2:全部的派生類都必須實現類型相關的虛函數

@3:每一個類中的類型虛函數都須要不一樣的實現

@4:咱們調用這個類對象的類型虛函數,就能夠知道當前類到底是子類仍是父類了。

例:


#include <iostream>

#include <string>


using namespace std;


/*

* 利用多態的方法,進行對象的動態類型識別,也就是區別判斷出,當前的父類指針指向的究竟是子類對象仍是父類對象。

*

*

*/


class Base

{

public:

virtual string type()

{

return "Base";

}

};


class child : public Base

{

public:

virtual string type() //子類重寫這個函數,到時用來判斷父類指針指向的究竟是父類對象仍是子類對象的

{

return "child";

}

void print()

{

cout << "I'm a child. " << endl;

}

};



void test(Base *b)

{

if ( b->type() == "child" )

{

child *c = static_cast<child*>(b);

c->print();

}

}


int main(void)

{

Base b;

child c;

test(&b);

test(&c);

return 0;

}


(2)多態解決方案的缺陷:


@1:必須從基類開始提供類型虛函數


@2:全部的派生類必須重寫類型虛函數


@3:每一個派生類的名字必須惟一



(3)C++提供了typeid關鍵字用與獲取類型信息,使用時要包含頭文件<typeinfo>


@1:typeid關鍵字返回對應參數的類型信息


@2:typeid返回一個type_info類對象,因此要包含頭文件typeinfo


@3:當typeid的參數爲NULL時將拋出異常


(4)typeid關鍵字的使用


int i = 0;


const type_info& tiv = typeid(i);

const type_info& tii = typeid(int);


cout << (tiv == tii) << endl; // 1


(5)typeid的注意事項


@1:當參數爲類型時:返回靜態類型信息(指望的類型)


@2:當參數爲變量時:

不存在虛函數表時:返回靜態類型信息

存在虛函數表時:返回動態類型信息(實際對象的類型)

#include <iostream>

#include <string>

#include <typeinfo>



using namespace std;


/*

* 利用typeid,進行對象的動態類型識別,也就是區別判斷出,當前的父類指針指向的究竟是子類對象仍是父類對象。

*

*

*/


class Base

{

public:

virtual ~Base()

{

}


};


class child : public Base

{

public:


};



void test(Base *b)

{

const type_info& tb = typeid(*b);

cout << tb.name() << endl;

}


int main(void)

{

int i = 0;

const type_info& tiv = typeid(i);

const type_info& tii = typeid(int);

cout << (tii == tiv) << endl;

Base b;

child c;

test(&b);

test(&c);

return 0;

}

相關文章
相關標籤/搜索