天天看點

C++程式設計思想——運作時類型識别

運作時類型識别

C++中有兩種方法可以識别目前運作的類型資訊

1、dynamic_cast,記得我們之前多态提及向上類型轉換,試圖用基類來調用子類的方法,當然了需要虛函數的輔助,其實類型的資訊正是虛函數的第一個slot中的内容。使用該關鍵字實作的稱為向下類型轉換。

class Security
{
public:
	virtual ~Security(){}
};

class Stock:public Security{};

class Bond:public Security{};

class Investment:public Security
{
public:
	void special()
	{
		std::cout<<"special Investment function"<<std::endl;
	}
};

class Metal:public Investment{};
           
int main()
{
	vector<Security *>portfolio;
	portfolio.push_back(new Metal);
	portfolio.push_back(new Investment);
	portfolio.push_back(new Bond);
	portfolio.push_back(new Stock);
	for (vector<Security *>::iterator it=portfolio.begin();it!=portfolio.end();++it)
	{
		Investment * cm=dynamic_cast<Investment *>(*it);
		if (cm)
		{
			cm->special();
		}
		else
			cout<<"not a Investment"<<endl;
	}
	cout<<"cast from intermediate pointer"<<endl;
	Security * sp=new Metal;

	Investment * cp=dynamic_cast<Investment * >(sp);
	if (cp)
	{
		cout<<"it is an investment"<<endl;
	}
	Metal *mp=dynamic_cast<Metal*>(sp);
	if (mp)
	{
		cout<<"it is a Metal too"<<endl;
	}
}
           

運作結果:

C++程式設計思想——運作時類型識别

從結果中我們可以發現dymatic_cast能夠在多層的繼承結構中将類型轉換到中間類型。

2、typeid操作符

該操作符傳回一個type_info常量對象的引用。當沒有虛函數的時候,typeid傳回基類位址。Dymatic_cast的開銷比typeid大。如果p為指針,type(*p)傳回的是派生類類型,typeid(p)傳回基類類型。r 為引用類型,typeid(p)為派生類的,typeid(&p)為基類類型。

3、RTTI在編譯時和運作時都會産生開銷。取得指向虛函數表指針,得到type_info指針,産生一個對type_info結構的引用,雙指針的解析。還要判斷其基類。構造函數等,但是RTTI引入使得在加入新類型時,必須确定新加入的類型不會導緻問題,是以這樣的不确定性等都應該慎用這個技術。

4、不能對void指針進行映射,它就是無類型資訊的。