日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
C++20類型轉(zhuǎn)換指南:使用場(chǎng)景與優(yōu)秀實(shí)踐

類型轉(zhuǎn)換 (Casts)

C++ 提供了五種特定的類型轉(zhuǎn)換:const_cast<>()、static_cast<>()、reinterpret_cast<>()、dynamic_cast<>() 和 C++20 引入的 std::bit_cast<>()。

請(qǐng)注意,舊的 C 風(fēng)格類型轉(zhuǎn)換(如 (int)myFloat)在 C++ 中仍然有效,并在現(xiàn)有代碼庫(kù)中廣泛使用。C 風(fēng)格的類型轉(zhuǎn)換涵蓋了所有四種 C++ 類型轉(zhuǎn)換,因此它們更容易出錯(cuò),因?yàn)槟噲D實(shí)現(xiàn)的目的并不總是顯而易見的,可能會(huì)得到意外的結(jié)果。我強(qiáng)烈建議您在新代碼中只使用 C++ 風(fēng)格的類型轉(zhuǎn)換,因?yàn)樗鼈兏踩?,且在代碼中更加突出。

虛擬基類

模糊基類出現(xiàn)在多個(gè)父類共有一個(gè)共同的父類時(shí)。推薦的解決方案是確保共享的父類自身不具有任何功能。這樣,其方法永遠(yuǎn)不會(huì)被調(diào)用,從而避免了歧義問題。C++ 還有另一種機(jī)制,稱為虛擬基類,用于解決您希望共享的父類具有自己功能的情況。

如果共享的父類是一個(gè)虛擬基類,則不會(huì)有任何歧義。以下代碼在 Animal 基類中添加了一個(gè) sleep() 方法,并修改了 Dog 和 Bird 類,使它們作為虛擬基類從 Animal 繼承。如果不使用虛擬基類,對(duì) DogBird 對(duì)象的 sleep() 調(diào)用將是模糊的,并會(huì)生成編譯器錯(cuò)誤,因?yàn)?nbsp;DogBird 將具有兩個(gè) Animal 子對(duì)象,一個(gè)來(lái)自 Dog,一個(gè)來(lái)自 Bird。然而,當(dāng) Animal 被虛擬繼承時(shí),DogBird 只有一個(gè) Animal 類的子對(duì)象,因此調(diào)用 sleep() 不會(huì)有歧義。

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(); // 因?yàn)樘摂M基類而不模糊
}

注意:虛擬基類是避免類層次結(jié)構(gòu)中歧義的好方法。

類型轉(zhuǎn)換 (Casts)

C++ 提供了五種特定的類型轉(zhuǎn)換:const_cast<>()、static_cast<>()、reinterpret_cast<>()、dynamic_cast<>() 和 C++20 引入的 std::bit_cast<>()。第一種在第 1 章中討論過(guò)。第 1 章還介紹了用于某些基本類型之間轉(zhuǎn)換的 static_cast<>(),但在繼承的上下文中還有更多內(nèi)容。現(xiàn)在您已經(jīng)熟悉編寫自己的類并理解類繼承,是時(shí)候更仔細(xì)地看看這些類型轉(zhuǎn)換了。

請(qǐng)注意,舊的 C 風(fēng)格類型轉(zhuǎn)換(如 (int)myFloat)在 C++ 中仍然有效,并在現(xiàn)有代碼庫(kù)中廣泛使用。C 風(fēng)格的類型轉(zhuǎn)換涵蓋了所有四種 C++ 類型轉(zhuǎn)換,因此它們更容易出錯(cuò),因?yàn)槟噲D實(shí)現(xiàn)的目的并不總是顯而易見的,可能會(huì)得到意外的結(jié)果。我強(qiáng)烈建議您在新代碼中只使用 C++ 風(fēng)格的類型轉(zhuǎn)換,因?yàn)樗鼈兏踩?,且在代碼中更加突出。

static_cast()

(1) 使用場(chǎng)景

static_cast()用于執(zhí)行語(yǔ)言直接支持的顯式轉(zhuǎn)換。例如,將int轉(zhuǎn)換為double以避免整數(shù)除法:

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

static_cast() 也可用于執(zhí)行因用戶定義的構(gòu)造函數(shù)或轉(zhuǎn)換例程而允許的顯式轉(zhuǎn)換。例如,如果類 A 有一個(gè)接受 B 對(duì)象的構(gòu)造函數(shù),則可以使用 static_cast() 將 B 對(duì)象轉(zhuǎn)換為 A 對(duì)象。

(2) 在繼承中的應(yīng)用

static_cast()可用于繼承層次結(jié)構(gòu)中的向下轉(zhuǎn)型:

class Base { /* ... */ };
class Derived : public Base { /* ... */ };

Base* b { nullptr };
Derived* d { new Derived{} };
b = d; // 向上轉(zhuǎn)型,不需要轉(zhuǎn)換。
d = static_cast(b); // 向下轉(zhuǎn)型,需要轉(zhuǎn)換。

(3) 注意事項(xiàng)

  • static_cast() 不執(zhí)行運(yùn)行時(shí)類型檢查??梢詫⑷魏?nbsp;Base 指針轉(zhuǎn)換為 Derived 指針,即使 Base 實(shí)際上不是 Derived。
  • static_cast() 不是萬(wàn)能的,它不能將一種類型的指針轉(zhuǎn)換為另一種完全無(wú)關(guān)的類型的指針,也不能在沒有轉(zhuǎn)換構(gòu)造函數(shù)的情況下直接將一種類型的對(duì)象轉(zhuǎn)換為另一種類型的對(duì)象。

reinterpret_cast()

(1) 使用場(chǎng)景

  • reinterpret_cast() 比 static_cast() 更強(qiáng)大但同時(shí)也更不安全。它用于執(zhí)行 C++ 類型規(guī)則技術(shù)上不允許的某些轉(zhuǎn)換。
  • 可以用來(lái)將一種類型的引用轉(zhuǎn)換為另一種類型的引用,即使類型之間完全無(wú)關(guān)。
  • 常用于將指針類型轉(zhuǎn)換為任何其他指針類型,包括將任何類型的指針轉(zhuǎn)換為 void*。

(2) 注意事項(xiàng)

  • 使用 reinterpret_cast() 要格外小心,因?yàn)樗试S你在不執(zhí)行任何類型檢查的情況下進(jìn)行轉(zhuǎn)換。
  • 可以用 reinterpret_cast() 將指針轉(zhuǎn)換為足夠大以容納它的整型類型,反之亦然。但是,嘗試將 64 位指針轉(zhuǎn)換為 32 位整數(shù)會(huì)導(dǎo)致編譯錯(cuò)誤。

std::bit_cast()

(1) 特點(diǎn)

  • std::bit_cast() 是 C++20 中引入的,定義在  頭文件中。
  • 它是標(biāo)準(zhǔn)庫(kù)中唯一的類型轉(zhuǎn)換,其他類型轉(zhuǎn)換是 C++ 語(yǔ)言本身的一部分。
  • bit_cast() 類似于 reinterpret_cast(),但它創(chuàng)建一個(gè)給定目標(biāo)類型的新對(duì)象,并將源對(duì)象的位復(fù)制到這個(gè)新對(duì)象中。它有效地將源對(duì)象的位解釋為目標(biāo)對(duì)象的位。
  • bit_cast() 要求源對(duì)象和目標(biāo)對(duì)象的大小相同且都是平凡可復(fù)制的。

(2) 示例

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

(3) 應(yīng)用場(chǎng)景

bit_cast() 的一個(gè)用例是用于平凡可復(fù)制類型的二進(jìn)制 I/O。例如,可以將這些類型的單個(gè)字節(jié)寫入文件,讀取文件時(shí),可以使用 bit_cast() 正確解釋從文件讀取的字節(jié)。

平凡可復(fù)制類型通常具有以下特征:

  • 無(wú)自定義析構(gòu)函數(shù):類型沒有自定義的析構(gòu)函數(shù)。
  • 無(wú)自定義或虛擬構(gòu)造函數(shù):類型沒有自定義的構(gòu)造函數(shù),也沒有虛擬構(gòu)造函數(shù)。
  • 無(wú)虛函數(shù)和虛基類:類型不包含虛函數(shù),并且不從虛基類繼承。
  • 可簡(jiǎn)單拷貝其狀態(tài):類型的所有成員可以通過(guò)簡(jiǎn)單的內(nèi)存拷貝來(lái)復(fù)制,沒有需要特殊處理的成員(如指針或動(dòng)態(tài)分配的資源)。

dynamic_cast()

(1) 特點(diǎn)

  • dynamic_cast() 在繼承層次結(jié)構(gòu)中提供了運(yùn)行時(shí)類型檢查。
  • 它可以用于轉(zhuǎn)換指針或引用。
  • 如果轉(zhuǎn)換沒有意義,dynamic_cast() 將返回空指針(對(duì)于指針版本)或拋出 std::bad_cast 異常(對(duì)于引用版本)。

(2) 示例

Base* b;
Derived* d { new Derived{} };
b = d;
d = dynamic_cast(b);

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

(3) 與其他類型轉(zhuǎn)換的區(qū)別

  • 與 static_cast() 或 reinterpret_cast() 不同,dynamic_cast() 執(zhí)行運(yùn)行時(shí)(動(dòng)態(tài))類型檢查,而后者即使轉(zhuǎn)換錯(cuò)誤也會(huì)執(zhí)行轉(zhuǎn)換。
  • 為了使用 dynamic_cast(),你的類必須至少有一個(gè)虛擬方法。如果類沒有虛擬表(vtable),嘗試使用 dynamic_cast() 將導(dǎo)致編譯錯(cuò)誤。

C++ 類型轉(zhuǎn)換總結(jié)

情境

推薦的轉(zhuǎn)換方法

說(shuō)明

移除 const 屬性

const_cast()

用于移除對(duì)象的 const 屬性

語(yǔ)言直接支持的顯式轉(zhuǎn)換

static_cast()

例如,從 int 轉(zhuǎn)換到 double 或 bool

用戶定義的構(gòu)造函數(shù)或轉(zhuǎn)換支持的顯式轉(zhuǎn)換

static_cast()

用于用戶定義的轉(zhuǎn)換

一個(gè)類的對(duì)象轉(zhuǎn)換為另一個(gè)(無(wú)關(guān))類的對(duì)象

bit_cast()

用于無(wú)關(guān)類之間的對(duì)象轉(zhuǎn)換

同一繼承層次中的類的指針對(duì)象轉(zhuǎn)換

dynamic_cast() (推薦) 或 static_cast()

用于繼承層次中的指針對(duì)象轉(zhuǎn)換

同一繼承層次中的類的引用對(duì)象轉(zhuǎn)換

dynamic_cast() (推薦) 或 static_cast()

用于繼承層次中的引用對(duì)象轉(zhuǎn)換

不相關(guān)類型的指針轉(zhuǎn)換

reinterpret_cast()

用于完全不相關(guān)的指針類型之間的轉(zhuǎn)換

不相關(guān)類型的引用轉(zhuǎn)換

reinterpret_cast()

用于完全不相關(guān)的引用類型之間的轉(zhuǎn)換

函數(shù)指針之間的轉(zhuǎn)換

reinterpret_cast()

用于函數(shù)指針之間的轉(zhuǎn)換

注意事項(xiàng)

  • 使用 const_cast() 應(yīng)謹(jǐn)慎,因?yàn)樗淖兞藢?duì)象的 const 性質(zhì)。
  • static_cast() 是最常用的轉(zhuǎn)換類型,適用于許多標(biāo)準(zhǔn)和用戶定義的轉(zhuǎn)換。
  • bit_cast() 用于位級(jí)別的類型轉(zhuǎn)換,要求源和目標(biāo)類型大小相同且都是平凡可復(fù)制的。
  • dynamic_cast() 在繼承層次中提供運(yùn)行時(shí)類型檢查,但要求類至少有一個(gè)虛擬方法。
  • reinterpret_cast() 提供更廣泛的轉(zhuǎn)換能力,但也帶來(lái)更高的風(fēng)險(xiǎn),因?yàn)樗粓?zhí)行類型檢查。

新聞標(biāo)題:C++20類型轉(zhuǎn)換指南:使用場(chǎng)景與優(yōu)秀實(shí)踐
瀏覽地址:http://www.5511xx.com/article/cdhhjjd.html