C++的四種cast(顯示類型轉換)


舊式的類型轉換中有倆種(Effect C++)

//C風格
(T)expression

(int)a//比如這樣子
//函數風格 T(expression)

doSomeWork(Widget(15)) 這里15作為一個參數給類Widget,會以轉型動作創建一個Widget

而C++提供了四種新式轉換。

(1)const_cast:通常用來把對象的常量性一處掉,是唯一有此能力的C++ style轉型操作符。

(2)dynamic_cast:用來指向安全向下轉型

是這樣的,比如有一個base類,有很多派生類,在這個繼承體系里,可以用來決定對象是否歸屬於繼承體系中的某個類型(向下的,也就是從基類指針轉變到某個派生類指針)

這是唯一一個無法通過舊式語法執行的動作,是唯一可能耗費重大運行成本的轉型動作。

成本非常高昂。

(3)static_cast:用來強迫隱式轉換。

比如把non-const對象轉換為const對象(反過來不行,只有const_cast能做到),或者把int轉為double等,還可以把void*指針轉為typed指針,把pointer-to-base轉為pointer-to-derived。

(4)reinterpret_cast:意圖執行低級轉型,效果取決於編譯器。

用於進行各種不同類型的指針之間、不同類型的引用之間以及指針和能容納指針的整數類型之間的轉換。

這個類型轉換會重新去解釋內存中存放的數據的類型,比如說我們強行把一個指向int型的指針(在內存中就是一個整數,只不過是用來解釋為地址的),去解釋為一個int,它可以滿足各種類型的轉換,但是對結果不做保證。

#include <iostream>
using namespace std;
int main()
{
    int a = 1;
    int* p1 = &a;
    char* p2 = reinterpret_cast<char*>(p1);
    double* p3 = reinterpret_cast<double*>(p1);

    cout << a << "  " << *p2 << "  " << *p3 << endl;
}

 

不管是p1,p2,還是p3,指向的都是同一個地址0x0116FA10,里面存放的是a的值,1。

 

 ,其他都是一樣的。

 

 

 輸出結果確是按各自指針類型來解釋的。

 

轉型實際上是會產生一些代碼的,比如說int和double在內存里表示形式不同,如果我們把int數轉型為double,那在內存中存儲的數據肯定是會改變的,是做了改變的。

 

//還有一個有趣的事情,

//基類
class Window{
publicvirtual void onRize(){...}
  ...
}

//派生類
class SpecialWindow:public Window{
publicvirtual void onResize()
  {
     //轉型,試圖調用Window的onRize();
    //這是行不通的!
    static_cast<Window>(*this).onResize();
  }

  ...//secialWindows專屬行為
}

這一段程序希望吧*this轉型為Window,然后調用Window::onResize。但是實際上,它調用的並不是當前對象上的函數,而是稍早轉型動作所建立的一個"*this對象之base class成分”的暫時副本身上的onResize

函數就是函數,成員函數只有一份,“調用哪個對象身上的函數”有什么關系呢,關鍵在於成員函數身上都有一個(非靜態的)*this指針,會影響到成員函數操作的數據。

所以實際上!他不是在當前對象身上,調用Window::onResize之后,再執行SecialWindow專屬動作,他調用的是哪個臨時副本,。如果Window::onResize修改了對象的內容,當前的對象其實沒有改動,改動的是副本。而SecialWindow::如果改動對象,就真的會改動。

為了避免這種情況,最好這樣寫

 

virtual void onResize()
{
   Window::onResize();//調用Window::onResize作用於*this的指針上
}

 

 

//-----之后也許需要補充一些dynamic_cast相關的問題。參見cherno的dynamic_cast相關視頻

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM