大家好,我是情報(bào)小哥~
1、所要解決的問題
在前面的相同專輯文章中,跟大家介紹過(guò)虛函數(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)用都是跟隨傳入的對(duì)象類型,這就是多態(tài);當(dāng)然如果此例子中Parent類中的print沒有virtual虛函數(shù)標(biāo)識(shí),則編譯器會(huì)認(rèn)為傳入的就是父類指針,從而只會(huì)調(diào)用父類的成員。
而從Test1或者Test2對(duì)象內(nèi)部看來(lái)并不能知道傳參是子類型還是父類型:
void Test1(Parent *ptr)
{
Child* ptrChild = (Child *)ptr;
ptrChild->dosomething(); //調(diào)用派生類成員
}
如上代碼如果傳入的參數(shù)是子類對(duì)象,那么函數(shù)內(nèi)部用子類類型指向該對(duì)象是正常運(yùn)行的,但如果此時(shí)傳入的是父類對(duì)象,而強(qiáng)制轉(zhuǎn)化為子類指針來(lái)使用,則程序就有可能出現(xiàn)未知錯(cuò)誤。
所以這里也引出來(lái)兩個(gè)概念:靜態(tài)類型與動(dòng)態(tài)類型
靜態(tài)類型: 即編譯期間所確定的變量類型;
動(dòng)態(tài)類型: 在運(yùn)行過(guò)程中指針或者引用所指向?qū)ο蟮膶?shí)際類型。
基于上面的風(fēng)險(xiǎn),我們急需有一種手段來(lái)識(shí)別變量的動(dòng)態(tài)類型,以進(jìn)行相應(yīng)的處理,我們通常叫其為:RTTI(Run-Time Type Identification,運(yùn)行時(shí)類型識(shí)別)
2、進(jìn)行動(dòng)態(tài)類型識(shí)別的方法
進(jìn)行動(dòng)態(tài)類型識(shí)別的方法挺多的,比如利用多態(tài)對(duì)派生類進(jìn)行相應(yīng)ID的標(biāo)識(shí)等等,不過(guò)推薦還是采用typeid的方式。
typeid關(guān)鍵字能夠獲得任意變量的類型信息,也是C++專門提供用于類型識(shí)別的方式。
那么下面我們就用一個(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)且正確的獲得識(shí)別,挺方便的。
最后有幾點(diǎn)需要注意下:
1、typeid返回值是名為type_info的標(biāo)準(zhǔn)庫(kù)類型的對(duì)象引用。
2、type_Info的name返回的是一個(gè)字符串,且其類名與實(shí)際程序中類型不一定是一致的,但是肯定是唯一標(biāo)識(shí)字符串,通過(guò)上面輸出結(jié)果大家也是可以了解到的。
最 后
好了,這里小哥就簡(jiǎn)單介紹了C++中動(dòng)態(tài)識(shí)別機(jī)制的使用,本系列文章后續(xù)還會(huì)更新,記得關(guān)注學(xué)習(xí)哦。
-
指針
+關(guān)注
關(guān)注
1文章
478瀏覽量
70491 -
虛函數(shù)
+關(guān)注
關(guān)注
0文章
8瀏覽量
1685 -
引用
+關(guān)注
關(guān)注
0文章
8瀏覽量
7720
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論