C 強制型別轉換運算子

2021-10-02 14:21:38 字數 3145 閱讀 4951

將型別名作為強制型別轉換運算子的做法是c語言的老式做法,c++ 為保持相容而予以保留。

c++引入了四種功能不同的強制型別轉換運算子:static_cast、reinterpret_cast、const_cast和dynamic_cast。

強制型別轉換有一定的風險,有的轉換不一定安全,如把整型數值轉換成指標,把基類指標轉換成派生類指標,把一種函式指標轉換成另一種函式指標,把常量指標轉換成非常量指標等。 c++ 引入新的強制型別轉換機制,主要是為了克服c語言強制型別轉換的以下三個缺點。

例如,將 int 強制轉換成 double 是沒有風險的,而將常量指標轉換成非常量指標,將基類指標轉換成派生類指標都是高風險的,而且後兩者帶來的風險不同(即可能引發不同種類的錯誤),c語言的強制型別轉換形式對這些不同並不加以區分。

強制型別轉換是引發程式執行時錯誤的乙個原因,因此在程式出錯時,可能就會想到是不是有哪些強制型別轉換出了問題。

如果採用c語言的老式做法,要在程式中找出所有進行了強制型別轉換的地方,顯然是很麻煩的,因為這些轉換沒有統一的格式。

而用 c++ 的方式,則只需要查詢_cast字串就可以了。甚至可以根據錯誤的型別,有針對性地專門查詢某一種強制型別轉換。例如,懷疑乙個錯誤可能是由於使用了 reinterpret_cast 導致的,就可以只查詢reinterpret_cast字串。

c++ 強制型別轉換運算子的用法如下:

《要轉換到的型別》 (待轉換的表示式)
例如:

double d = static_cast (3*5); //將 3*5 的值轉換成實數
下面分別介紹四種強制型別轉換運算子 。

static_cast用於進行比較「自然」和低風險的轉換,如整型和浮點型、字元型之間的互相轉換。另外,如果物件所屬的類過載了強制型別轉換運算子t (如 t 是 int、int* 或其他型別名) ,則 static_cast 也能用來進行物件到 t 型別的轉換

static_cast 用法示例如下:

#include using namespace std;

class a

operator char*()

};int main()

reinterpret_cast用於進行各種不同型別的指標之間、不同型別的引用之間以及指標和能容納指標的整數型別之間的轉換。 轉換時,執行的是逐個位元複製的操作。

這種轉換提供了很強的靈活性,但轉換的安全性只能由程式設計師的細心來保證了。例如,程式設計師執意要把乙個 int* 指標、函式指標或其他型別的指標轉換成 string* 型別的指標也是可以的,至於以後用轉換後的指標呼叫 string 類的成員函式引發錯誤,程式設計師也只能自行承擔查詢錯誤的煩瑣工作:(c++ 標準不允許將函式指標轉換成物件指標,但有些編譯器,如 visual studio 2010,則支援這種轉換)。

reinterpret_cast 用法示例如下:

#include using namespace std;

class a

};int main()

第 19 行的**不安全,因為在編譯器看來,pa->j 的存放位置就是 n 後面的 4 個位元組。 本條語句會向這 4 個位元組中寫入 500。但這 4 個位元組不知道是用來存放什麼的,貿然向其中寫入可能會導致程式錯誤甚至崩潰。

reinterpret_cast體現了 c++ 語言的設計思想:使用者可以做任何操作,但要為自己的行為負責。

const_cast運算子僅用於進行去除const屬性的轉換, 它也是四個強制型別轉換運算子中唯一能夠去除 const 屬性的運算子。

將 const 引用轉換為同型別的非 const 引用,將 const 指標轉換為同型別的非 const 指標時可以使用 const_cast 運算子。例如:

const string s = "inception";

string& p = const_cast (s);

string* ps = const_cast (&s); // &s 的型別是 const string*

//a,b 2個變數指向同乙個位址,只是a所在位址內容怎麼改變,a的值都不改變

const int a = 123;

int& b = const_cast(a);

b = 5;

int* c = const_cast(&a);

用 reinterpret_cast 可以將多型基類(包含虛函式的基類)的指標強制轉換為派生類的指標,但是這種轉換不檢查安全性,即不檢查轉換後的指標是否確實指向乙個派生類物件。dynamic_cast專門用於將多型基類的指標或引用強制轉換為派生類的指標或引用,而且能夠檢查轉換的安全性。對於不安全的指標轉換,轉換結果返回 null 指標。

dynamic_cast 是通過「執行時型別檢查」來保證安全性的。dynamic_cast 不能用於將非多型基類的指標或引用強制轉換為派生類的指標或引用——這種轉換沒法保證安全性,只好用 reinterpret_cast 來完成

dynamic_cast 示例程式如下:

#include #include using namespace std;

class base

};class derived : public base ;

int main()

程式的輸出結果是:

unsafe dynamic_cast1

第 20 行,通過判斷 pd 的值是否為 null,就能知道第 19 行進行的轉換是否是安全的。第 23 行同理。

如果上面的程式**現了下面的語句:

derived & r = dynamic_cast (b);
那該如何判斷該轉換是否安全呢?不存在空引用,因此不能通過返回值來判斷轉換是否安全。c++ 的解決辦法是:dynamic_cast在進行引用的強制轉換時,如果發現轉換不安全,就會丟擲乙個異常,通過處理異常,就能發現不安全的轉換。

強制轉換運算子和型別強制轉換運算子

char b a cout int b endl 在 c 中,型別的名字 包括類的名字 本身也是一種運算子,即型別強制轉換運算子。型別強制轉換運算子是單目運算子,也可以被過載,但只能過載為成員函式,不能過載為全域性函式。經過適當過載後,型別名 物件這個對物件進行強制型別轉換的表示式就等價於物件.op...

C 強制型別轉換運算子

c 將型別名作為強制型別轉換運算子。c 引入了四種功能不同的強制型別轉換運算子以進行強制型別轉換 static cast reinterpret cast const cast 和 dynamic cast。強制型別轉換是有一定風險的,有的轉換並不一定安全,如把整型數值轉換成指標,把基類指標轉換成派...

C 過載強制型別轉換運算子

c 中,型別的名字 包括類的名字 本身也是一種運算子,即型別強制轉換運算子。型別強制轉換運算子是單目運算子,也可以被過載,但只能過載為成員函式,不能過載為全域性函式。經過適當過載後,型別名 物件這個對物件進行強制型別轉換的表示式就等價於物件.operator 型別名 即變成對運算子函式的呼叫。對 d...