日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++之dynamic_cast、static_cast、const_cast、reinterpret_cast的用法和区别

發布時間:2025/1/21 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++之dynamic_cast、static_cast、const_cast、reinterpret_cast的用法和区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡述

C++中有四個類型轉換符,旨在嚴格限制允許的類型轉換,使轉換更規范。這四個轉換符分別是:

  • dynamic_cast
  • static_cast
  • const_cast
  • reinterpret_cast

可以根據目的選擇一個適合的運算符,而不是使用通用的類型轉換。讓編譯器能夠檢查程序的行為是否與設計者想法吻合。

接下來看看每個類型轉換符的用法以及它們之間的區別。

dynamic_cast

之前在 “C++之 RTTI”中講到過dynamic_cast,dynamic_cast是動態轉換,使用該轉換符時會自動去檢查轉換類型,以及轉換是否合法。它的用途是,使得能夠在類層次結構中進行向上轉換(由于是 is-a關系,這樣的類型轉換是安全的),而不允許其他轉換。

語法為:
dynamic_cast<type-name> (expression)

舉個栗子:
一個基類 Base(必須要是虛基類,帶有虛函數),一個繼承于Base 的派生類 A,那么

Base * pbase = new Base(); A * pA = new A();Base * pB = dynamic_cast\<Base*>(pA); //成立 A * pA1 = dynamic_cast\<A*>(pbase); //不成立

也就是說,dynamic_cast不能從多態性的虛基類強制到某個派生類或者兄弟類。dynamic_cast要求多態性的操作對象。
如果轉換不合法,將會返回空指針,就比如上面那句不成立的轉化,返回一個空指針。

需要注意的是:編譯器不能讀由 void所指向的存儲提供任何保證。這也就意味著dynamic_cast不能從 void觸發進行強制轉換,因為它必須去查看對象,以便確定其類型,對于這種情況就需要 static_cast了。

缺點:這是為了保證轉換的合法性,dynamic_cast會帶來一點運行時的額外開銷。

static_cast

靜態轉換static_cast,和dynamic_cast不同的是,它不需要檢查被強制轉換的對象。

語法為:
static_cast<type-name> (expression)

僅當 type_name 可被隱式轉換為 expression 所屬的類型或 expression 可被隱式轉換為 type_name 所屬的類型時,上述轉換才是合法的,否則將會出錯。
比如說:A 是 B 的基類,而 C 是一個無關的類,那么從 A 到 B 的轉換,從 B 到 A 的轉換都是合法的,而從A到 C 轉換是不允許的。

A a; B b; A * pA = static_cast<A *>(&b); //允許 B * pB = static_cast<B *>(&a); //允許 C * pC = static_cast<C *>(&b); //不允許

第一種轉換是合法的,因為向上轉換可以顯示地進行。第二種轉換是從基類指針到派生類指針,在不進行顯示類型轉換的情況下,將無法進行。但是由于無需進行類型轉換,便可以進行另一個方向的類型轉換,因此使用 static_cast 來進行向下轉換是合法的。
也就是說,可以從常規基類強制,不能從虛基類強制。比如 A 如果是 B 的常規基類,沒有虛函數,這樣是可以向下轉換的,如果 A 是B 的虛基類,就不能轉換。

const_cast

const_cast運算符用于執行只有一種用途的類型轉換,即改變值為 const 或 volatile,其語法也是一樣的:
const_cast<type-name> (expression)

注意:這里的type-name和expression類型必須相同,除了 const 和 volatile 特征(有或無)可以不同。
比如 A 和 B 兩個類:

A bar; const A * pBar = &bar;A * pA = const_cast<A *>(pBar); //合法 const B * pB = const_cast<B *>(pBar); //不合法

第一個類型轉換使得*pA成為一個可用于修改 bar 的對象值的指針,它刪除 const 標簽,第二個類型轉換是非法的,因為它同時嘗試將類型從 const A * 改為 const B *.

const_cast 的用途,有時候可能需要這樣一個值,它在大多數時候是常量,而有時候又是可以修改的,在這種情況下,可以將這個值聲明為 const,并在需要修改它的時候,使用 const_cast 。這也可以通過通用類型轉換來實現,但通用轉換也可能同時改變類型:

A bar; const A * pBar = &bar;A * pA = (A *)(pBar); //合法 B * pB = (B *)(pBar); //合法

由于編程時可能無意間同時改變類型和常量特征,因此使用 const_cast運算符更安全。

但是,const_cast并不是萬能的,它可以修改指向一個值的指針,但是修改 const 值的結果是不確定的,來看個示例:

#include <iostream>using namespace std;void change(const int * pt,int n) {int * pc;pc = const_cast<int *>(pt);*pc += n; }int main() {int pop1 = 100;const int pop2 = 50;cout << "pop1 = " << pop1 << " pop2 = " << pop2 << endl;change(&pop1,20);change(&pop2,20);cout << "pop1 = " << pop1 << " pop2 = " << pop2 << endl;return 0; }

輸出結果:

pop1 = 100 pop2 = 50 pop1 = 120 pop2 = 50

可以看到,由于 pop2被聲明為 const,因此編譯器可能禁止修改它。所以 const_cast 可用來刪除 const 的特征,但僅當指向的值不是 const 時才可行。

reinterpret_cast

reinterpret_cast用于天生危險的類型轉換,reinterpret中文含義就是“重新詮釋”,它可以用于不同類型之間的轉換,也就是說可以將數據以二進制存在形式的重新解釋。但并不是所有類型都可以轉換的。
語法:reinterpret_cast<type-name> (expression)

示例:

struct dat{ short a; short b; }; long value = 0xA224B118; dat * pd = reinterpret_cast<dat *>(&value); cout << pd->a;

通常這樣的轉換適用于依賴于實現的底層編程技術,是不可移植的。例如,不同系統在存儲多字節整型時,可能以不同順序存儲其中的字節。

然而,需要注意的是reinterpret_cast運算符并不支持所有的類型轉換,例如,可以將指針類型轉換為足以存儲指針表示的整型,但不能將指針轉換為更小的整型或浮點型。另一個限制是,不能將函數指針轉換為數據指針,反之亦然。

什么情況下可以用到這個轉換符:

  • 從指針類型到一個足夠大的整數類型
  • 從整數類型或者枚舉類型到指針類型
  • 從一個指向函數的指針到另一個不同類型的指向函數的指針
  • 從一個指向對象的指針到另一個不同類型的指向對象的指針
  • 從一個指向類函數成員的指針到另一個指向不同類型的函數成員的指針
  • 從一個指向類數據成員的指針到另一個指向不同類型的數據成員的指針

參考資料《c++程序設計語言》、《C++編程思想》

總結

以上是生活随笔為你收集整理的C++之dynamic_cast、static_cast、const_cast、reinterpret_cast的用法和区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。