AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

C++ 20類型轉換指南:使用場景與優秀實踐

來源: 責編: 時間:2023-11-20 08:58:11 330觀看
導讀類型轉換 (Casts)C++ 提供了五種特定的類型轉換:const_cast<>()、static_cast<>()、reinterpret_cast<>()、dynamic_cast<>() 和 C++20 引入的 std::bit_cast<>()。請注意,舊的 C 風格類型轉換(如 (int)myFloat)在 C++ 中

類型轉換 (Casts)

C++ 提供了五種特定的類型轉換:const_cast<>()、static_cast<>()、reinterpret_cast<>()、dynamic_cast<>() 和 C++20 引入的 std::bit_cast<>()。SiY28資訊網——每日最新資訊28at.com

請注意,舊的 C 風格類型轉換(如 (int)myFloat)在 C++ 中仍然有效,并在現有代碼庫中廣泛使用。C 風格的類型轉換涵蓋了所有四種 C++ 類型轉換,因此它們更容易出錯,因為您試圖實現的目的并不總是顯而易見的,可能會得到意外的結果。我強烈建議您在新代碼中只使用 C++ 風格的類型轉換,因為它們更安全,且在代碼中更加突出。SiY28資訊網——每日最新資訊28at.com

SiY28資訊網——每日最新資訊28at.com

虛擬基類

模糊基類出現在多個父類共有一個共同的父類時。推薦的解決方案是確保共享的父類自身不具有任何功能。這樣,其方法永遠不會被調用,從而避免了歧義問題。C++ 還有另一種機制,稱為虛擬基類,用于解決您希望共享的父類具有自己功能的情況。SiY28資訊網——每日最新資訊28at.com

如果共享的父類是一個虛擬基類,則不會有任何歧義。以下代碼在 Animal 基類中添加了一個 sleep() 方法,并修改了 Dog 和 Bird 類,使它們作為虛擬基類從 Animal 繼承。如果不使用虛擬基類,對 DogBird 對象的 sleep() 調用將是模糊的,并會生成編譯器錯誤,因為 DogBird 將具有兩個 Animal 子對象,一個來自 Dog,一個來自 Bird。然而,當 Animal 被虛擬繼承時,DogBird 只有一個 Animal 類的子對象,因此調用 sleep() 不會有歧義。SiY28資訊網——每日最新資訊28at.com

class Animal {public:    virtual void eat() = 0;    virtual void sleep() { cout << "zzzzz...." << endl; }};class Dog : public virtual Animal {public:    virtual void bark() { cout << "Woof!" << endl; }    void eat() override { cout << "The dog ate." << endl; }};class Bird : public virtual Animal {public:    virtual void chirp() { cout << "Chirp!" << endl; }    void eat() override { cout << "The bird ate." << endl; }};class DogBird : public Dog, public Bird {public:    void eat() override { Dog::eat(); }};int main() {    DogBird myConfusedAnimal;    myConfusedAnimal.sleep(); // 因為虛擬基類而不模糊}

注意:虛擬基類是避免類層次結構中歧義的好方法。SiY28資訊網——每日最新資訊28at.com

SiY28資訊網——每日最新資訊28at.com

類型轉換 (Casts)

C++ 提供了五種特定的類型轉換:const_cast<>()、static_cast<>()、reinterpret_cast<>()、dynamic_cast<>() 和 C++20 引入的 std::bit_cast<>()。第一種在第 1 章中討論過。第 1 章還介紹了用于某些基本類型之間轉換的 static_cast<>(),但在繼承的上下文中還有更多內容。現在您已經熟悉編寫自己的類并理解類繼承,是時候更仔細地看看這些類型轉換了。SiY28資訊網——每日最新資訊28at.com

請注意,舊的 C 風格類型轉換(如 (int)myFloat)在 C++ 中仍然有效,并在現有代碼庫中廣泛使用。C 風格的類型轉換涵蓋了所有四種 C++ 類型轉換,因此它們更容易出錯,因為您試圖實現的目的并不總是顯而易見的,可能會得到意外的結果。我強烈建議您在新代碼中只使用 C++ 風格的類型轉換,因為它們更安全,且在代碼中更加突出。SiY28資訊網——每日最新資訊28at.com

static_cast()

(1) 使用場景SiY28資訊網——每日最新資訊28at.com

static_cast()用于執行語言直接支持的顯式轉換。例如,將int轉換為double以避免整數除法:SiY28資訊網——每日最新資訊28at.com

int i { 3 };int j { 4 };double result { static_cast<double>(i) / j };

static_cast() 也可用于執行因用戶定義的構造函數或轉換例程而允許的顯式轉換。例如,如果類 A 有一個接受 B 對象的構造函數,則可以使用 static_cast() 將 B 對象轉換為 A 對象。SiY28資訊網——每日最新資訊28at.com

(2) 在繼承中的應用SiY28資訊網——每日最新資訊28at.com

static_cast()可用于繼承層次結構中的向下轉型:SiY28資訊網——每日最新資訊28at.com

class Base { /* ... */ };class Derived : public Base { /* ... */ };Base* b { nullptr };Derived* d { new Derived{} };b = d; // 向上轉型,不需要轉換。d = static_cast<Derived*>(b); // 向下轉型,需要轉換。

(3) 注意事項SiY28資訊網——每日最新資訊28at.com

  • static_cast() 不執行運行時類型檢查。可以將任何 Base 指針轉換為 Derived 指針,即使 Base 實際上不是 Derived。
  • static_cast() 不是萬能的,它不能將一種類型的指針轉換為另一種完全無關的類型的指針,也不能在沒有轉換構造函數的情況下直接將一種類型的對象轉換為另一種類型的對象。

reinterpret_cast()

(1) 使用場景SiY28資訊網——每日最新資訊28at.com

  • reinterpret_cast() 比 static_cast() 更強大但同時也更不安全。它用于執行 C++ 類型規則技術上不允許的某些轉換。
  • 可以用來將一種類型的引用轉換為另一種類型的引用,即使類型之間完全無關。
  • 常用于將指針類型轉換為任何其他指針類型,包括將任何類型的指針轉換為 void*。

(2) 注意事項SiY28資訊網——每日最新資訊28at.com

  • 使用 reinterpret_cast() 要格外小心,因為它允許你在不執行任何類型檢查的情況下進行轉換。
  • 可以用 reinterpret_cast() 將指針轉換為足夠大以容納它的整型類型,反之亦然。但是,嘗試將 64 位指針轉換為 32 位整數會導致編譯錯誤。

std::bit_cast()

(1) 特點SiY28資訊網——每日最新資訊28at.com

  • std::bit_cast() 是 C++20 中引入的,定義在 <bit> 頭文件中。
  • 它是標準庫中唯一的類型轉換,其他類型轉換是 C++ 語言本身的一部分。
  • bit_cast() 類似于 reinterpret_cast(),但它創建一個給定目標類型的新對象,并將源對象的位復制到這個新對象中。它有效地將源對象的位解釋為目標對象的位。
  • bit_cast() 要求源對象和目標對象的大小相同且都是平凡可復制的。

(2) 示例SiY28資訊網——每日最新資訊28at.com

float asFloat { 1.23f };auto asUint { bit_cast<unsigned int>(asFloat) };if (bit_cast<float>(asUint) == asFloat) {    cout << "Roundtrip success." << endl;}

(3) 應用場景SiY28資訊網——每日最新資訊28at.com

bit_cast() 的一個用例是用于平凡可復制類型的二進制 I/O。例如,可以將這些類型的單個字節寫入文件,讀取文件時,可以使用 bit_cast() 正確解釋從文件讀取的字節。SiY28資訊網——每日最新資訊28at.com

平凡可復制類型通常具有以下特征:SiY28資訊網——每日最新資訊28at.com

SiY28資訊網——每日最新資訊28at.com

SiY28資訊網——每日最新資訊28at.com

  • 無自定義析構函數:類型沒有自定義的析構函數。
  • 無自定義或虛擬構造函數:類型沒有自定義的構造函數,也沒有虛擬構造函數。
  • 無虛函數和虛基類:類型不包含虛函數,并且不從虛基類繼承。
  • 可簡單拷貝其狀態:類型的所有成員可以通過簡單的內存拷貝來復制,沒有需要特殊處理的成員(如指針或動態分配的資源)。

dynamic_cast()

(1) 特點SiY28資訊網——每日最新資訊28at.com

  • dynamic_cast() 在繼承層次結構中提供了運行時類型檢查。
  • 它可以用于轉換指針或引用。
  • 如果轉換沒有意義,dynamic_cast() 將返回空指針(對于指針版本)或拋出 std::bad_cast 異常(對于引用版本)。

(2) 示例SiY28資訊網——每日最新資訊28at.com

Base* b;Derived* d { new Derived{} };b = d;d = dynamic_cast<Derived*>(b);Base base;Derived derived;Base& br { base };try {    Derived& dr { dynamic_cast<Derived&>(br) };} catch (const bad_cast&) {    cout << "Bad cast!" << endl;}

(3) 與其他類型轉換的區別SiY28資訊網——每日最新資訊28at.com

  • 與 static_cast() 或 reinterpret_cast() 不同,dynamic_cast() 執行運行時(動態)類型檢查,而后者即使轉換錯誤也會執行轉換。
  • 為了使用 dynamic_cast(),你的類必須至少有一個虛擬方法。如果類沒有虛擬表(vtable),嘗試使用 dynamic_cast() 將導致編譯錯誤。

C++ 類型轉換總結

情境
SiY28資訊網——每日最新資訊28at.com

推薦的轉換方法
SiY28資訊網——每日最新資訊28at.com

說明
SiY28資訊網——每日最新資訊28at.com

移除 const 屬性SiY28資訊網——每日最新資訊28at.com

const_cast()SiY28資訊網——每日最新資訊28at.com

用于移除對象的 const 屬性SiY28資訊網——每日最新資訊28at.com

語言直接支持的顯式轉換
SiY28資訊網——每日最新資訊28at.com

static_cast()SiY28資訊網——每日最新資訊28at.com

例如,從 int 轉換到 double 或 boolSiY28資訊網——每日最新資訊28at.com

用戶定義的構造函數或轉換支持的顯式轉換
SiY28資訊網——每日最新資訊28at.com

static_cast()SiY28資訊網——每日最新資訊28at.com

用于用戶定義的轉換
SiY28資訊網——每日最新資訊28at.com

一個類的對象轉換為另一個(無關)類的對象
SiY28資訊網——每日最新資訊28at.com

bit_cast()SiY28資訊網——每日最新資訊28at.com

用于無關類之間的對象轉換
SiY28資訊網——每日最新資訊28at.com

同一繼承層次中的類的指針對象轉換
SiY28資訊網——每日最新資訊28at.com

dynamic_cast() (推薦) 或 static_cast()SiY28資訊網——每日最新資訊28at.com

用于繼承層次中的指針對象轉換
SiY28資訊網——每日最新資訊28at.com

同一繼承層次中的類的引用對象轉換
SiY28資訊網——每日最新資訊28at.com

dynamic_cast() (推薦) 或 static_cast()SiY28資訊網——每日最新資訊28at.com

用于繼承層次中的引用對象轉換
SiY28資訊網——每日最新資訊28at.com

不相關類型的指針轉換
SiY28資訊網——每日最新資訊28at.com

reinterpret_cast()SiY28資訊網——每日最新資訊28at.com

用于完全不相關的指針類型之間的轉換
SiY28資訊網——每日最新資訊28at.com

不相關類型的引用轉換
SiY28資訊網——每日最新資訊28at.com

reinterpret_cast()SiY28資訊網——每日最新資訊28at.com

用于完全不相關的引用類型之間的轉換
SiY28資訊網——每日最新資訊28at.com

函數指針之間的轉換
SiY28資訊網——每日最新資訊28at.com

reinterpret_cast()SiY28資訊網——每日最新資訊28at.com

用于函數指針之間的轉換
SiY28資訊網——每日最新資訊28at.com

注意事項

  • 使用 const_cast() 應謹慎,因為它改變了對象的 const 性質。
  • static_cast() 是最常用的轉換類型,適用于許多標準和用戶定義的轉換。
  • bit_cast() 用于位級別的類型轉換,要求源和目標類型大小相同且都是平凡可復制的。
  • dynamic_cast() 在繼承層次中提供運行時類型檢查,但要求類至少有一個虛擬方法。
  • reinterpret_cast() 提供更廣泛的轉換能力,但也帶來更高的風險,因為它不執行類型檢查。

SiY28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-31013-0.htmlC++ 20類型轉換指南:使用場景與優秀實踐

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Go vs Rust:文件上傳性能比較

下一篇: C++14中的成員初始值設定項與聚合功能詳解

標簽:
  • 熱門焦點
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • 6月iOS設備性能榜:M2穩居榜首 A系列只能等一手3nm來救

    沒有新品發布,自然iOS設備性能榜的上榜設備就沒有什么更替,僅僅只有跑分變化而產生的排名變動,畢竟蘋果新品的發布節奏就是這樣的,一年下來也就幾個移動端新品,不會像安卓廠商,一
  • 5月安卓手機好評榜:魅族20 Pro奪冠

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數據來源安兔兔評測,收集時間2023年5月1日至5月31日,僅限國內市場。第一名:魅族20 Pro好評率:97.50%不得不感慨魅族老品牌還
  • 服務存儲設計模式:Cache-Aside模式

    Cache-Aside模式一種常用的緩存方式,通常是把數據從主存儲加載到KV緩存中,加速后續的訪問。在存在重復度的場景,Cache-Aside可以提升服務性能,降低底層存儲的壓力,缺點是緩存和底
  • 得物效率前端微應用推進過程與思考

    一、背景效率工程隨著業務的發展,組織規模的擴大,越來越多的企業開始意識到協作效率對于企業團隊的重要性,甚至是決定其在某個行業競爭中突圍的關鍵,是企業長久生存的根本。得物
  • 一篇文章帶你了解 CSS 屬性選擇器

    屬性選擇器對帶有指定屬性的 HTML 元素設置樣式。可以為擁有指定屬性的 HTML 元素設置樣式,而不僅限于 class 和 id 屬性。一、了解屬性選擇器CSS屬性選擇器提供了一種簡單而
  • 蘋果、三星、惠普等暫停向印度出口筆記本和平板電腦

    集微網消息,據彭博社報道,在8月3日印度突然禁止在沒有許可證的情況下向印度進口電腦/平板及顯示器等產品后,蘋果、三星電子和惠普等大公司暫停向印度
  • 自研Exynos回歸!三星Galaxy S24系列將提供Exynos和驍龍雙版本

    年初,全新的三星Galaxy S23系列發布,包含Galaxy S23、Galaxy S23+和Galaxy S23 Ultra三個版本,全系搭載超頻版驍龍8 Gen 2,雖同樣采用臺積電4nm工藝制
  • OPPO K11采用全方位護眼屏:三大護眼能力減輕視覺疲勞

    日前OPPO官方宣布,全新的OPPO K11將于7月25日正式發布,將主打旗艦影像,和同檔位競品相比,其最大的賣點就是將配備索尼IMX890主攝,堪稱是2000檔位影像表
Top