1. 程式人生 > >C++學習筆記(14) static_cast 與 dynamic_cast

C++學習筆記(14) static_cast 與 dynamic_cast

dynamic_cast運算子能夠在執行時將一個物件強制轉換成其實際型別:

實際應用場景:在C++學習筆記(13)中,在main.cpp裡面定義了displayGeometric()函式,

void displayGeometric(const Geometric& g)
{
    cout << g.toString() << endl;	
} 

假設現在需要對這個函式進行修改:

函式引數型別不變,當引數時rectangle型別的物件時,輸出width和height, 當引數是circle型別的物件時,輸出半徑 。

首先介紹一種錯誤的實現方法

void displayGeometric(const Geometric& g)
{
        cout << "The radius is " << g.getRadius() << endl;
	
	cout << "The width is " << g.getWidth() << endl;
	cout << "The height is " << g.getHeight() << endl;	
} 

很明顯,這種方法是無法通過編譯的!

在前面的學習中,知道static_cast能夠對變數進行強制型別轉換(靜態轉換)。能否通過static_cast實現呢?

void displayGeometric(const Geometric& g)
{
    Geometric* p = &g;

    cout << "The radius is " << static_cast<Circle*>(p)->getRadius() << endl;
	
    cout << "The width is " << static_cast<Rectangle*>(p)->getWidth() << endl;
    cout << "The height is " << static_cast<Rectangle*>(p)->getHeight() << endl;	
} 

這樣會存在函式 displayGeometric() 可能會將circle錯誤的轉化為rectangle而呼叫getWidth()方法。所以任然是錯誤的,因為static_cast()不能對轉換成功的結果進行檢查,而我們的要求是,在呼叫getRadius()之前必須確保物件是一個circle.

dynamic_cast與static_cast的功能類似,但是,dynamic_cast在執行時進行檢查從而保證轉換的成功進行。轉換失敗會返回NULL. 所以用dynamic_cast可以實現上面要求的功能

void displayGeometric(const Geometric& g)
{
	Geometric* p = &g;
	Circle* p1 = dynamic_cast<Circle*>(p);
	Rectangle* p2 = dynamic_cast<Rectangle*>(p);
	if(p1 != NULL)  // Circle類性轉換成功
	{
		cout << "The radius is " << p1->getRadius() << endl;
	} 
    
        if(p2 != NULL)  // Rectangle轉換成功
	{
	    cout << "The width is " << p2->getWidth() << endl;
    	cout << "The height is " << p2->getHeight() << endl;	
	} 	
} 

注:

dynamic_cast只能在多型型別的指標或者引用上使用,也就是說該型別必須包含虛擬函式,dynamic_cast可以在執行時檢查強制轉換是否成功。static_cast則在編譯的時候起作用。