C++學習筆記(14) static_cast 與 dynamic_cast
阿新 • • 發佈:2019-01-13
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則在編譯的時候起作用。