最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換

 更新時間:2021年03月05日 12:15:03   作者:Er_HU  
這篇文章主要給大家介紹了關(guān)于C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

引言

假設(shè)有基類 A,包含了虛函數(shù) func1,以及有派生類 B,繼承于類 A,派生類 B 中實現(xiàn)了函數(shù) func1。此時可以用 A 類型的指針指向 B 類型的對象,并用 A 類型的指針調(diào)用 B 類型對象中的函數(shù) func1。這時,就形成了多態(tài)。包含虛函數(shù)的類 A,我們也稱為多態(tài)類。

由于派生類 B 完整包含了 基類 A 的所有定義,將 B 類型的指針轉(zhuǎn)換為 A 類型的指針總是安全的。

而將 A 類型的指針強(qiáng)制轉(zhuǎn)換為 B 類型的指針時,如果 A 類型指針指向的對象確實為 B 類型的對象,那么轉(zhuǎn)換也是安全的。此時,該 B 類型對象被稱為完整對象(complete object)。

強(qiáng)制轉(zhuǎn)換有哪些類型?

C++ 包含了以下幾種強(qiáng)制轉(zhuǎn)換運算符,這些運算符用于消除老式 C 語言轉(zhuǎn)換中的存在的歧義和隱患:

  • dynamic_cast
  • static_cast
  • const_cast
  • reinterpret_cast
  • safe_cast

本文會著重介紹如何使用 dynamic_cast 和 static_cast。

提醒:

除非必須,不要使用 const_cast 和 reinterpret_cast,因為它們存在一些老式 C 語言轉(zhuǎn)換中的隱患。

dynamic_cast 運算符

語法:

 dynamic_cast <type-id> (expression)

type-id 必須是一個指針或者引用,指向/引用已定義的類類型或者 void。如果type-id 是指針,則 expression 必須也為指針類型,如果 type-id 是引用,expression 必須為左值類型。

如果 type-id 是 void*,那么在運行時將檢測 expression 的實際類型。其結(jié)果返回 expression 指向的完整對象。

如非需要,現(xiàn)代 C++ 中應(yīng)該避免使用 void 指針,因為容易出錯。

下面看些示例,了解 dynamic_cast 的使用方式。

示例1:

class Root { };
class Base : public Root { };
class Derived : public Base { };

void f(Derived* pd) {
 Base* pb = dynamic_cast<Base*>(pd); // ok: Base is a direct base class
         // pb points to Base subobject of pd
 Root* pr = dynamic_cast<Root*>(pd); // ok: Root is an indirect base class
         // pr points to Root subobject of pd
}

示例1 中提到了子對象(subobject)的概念,注意與子類型進(jìn)行區(qū)分:

  • Root 類型包含子類型 Base,Base 類型包含子類型 Derived。
  • Derived 對象包含了 Base 類型的子對象,Base 類型的子對象又包含了 Root 類型的子對象。

再聯(lián)系下前面說的:派生類完整包含了基類的所有定義。

示例2:

class B {virtual void f();};
class D : public B {virtual void f();};

void f() {
 B* pb = new D; // unclear but ok
 B* pb2 = new B;

 D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D
 D* pd2 = dynamic_cast<D*>(pb2); // pb2 was nullptr.
}

示例2 中 通過 dynamic_cast 轉(zhuǎn)換為 pd2 時,不會報錯,返回 nullptr。但如果同樣地情況轉(zhuǎn)換的對象是引用類型,那么運行時會拋出 std::bad_cast 異常。如果 pb2 指向/引用的對象無效,同樣也會拋出異常。

示例3:

#include <stdio.h>
#include <iostream>

struct A {
 virtual void test() {
  printf_s("in A\n");
 }
};

struct B : A {
 virtual void test() {
  printf_s("in B\n");
 }

 void test2() {
  printf_s("test2 in B\n");
 }
};

struct C : B {
 virtual void test() {
  printf_s("in C\n");
 }

 void test2() {
  printf_s("test2 in C\n");
 }
};

void Globaltest(A& a) {
 try {
  C &c = dynamic_cast<C&>(a);
  printf_s("in GlobalTest\n");
 }
 catch(std::bad_cast) {
  printf_s("Can't cast to C\n");
 }
}

int main() {
 A *pa = new C;
 A *pa2 = new B;

 pa->test();

 B * pb = dynamic_cast<B *>(pa);
 if (pb)
  pb->test2();

 C * pc = dynamic_cast<C *>(pa2);
 if (pc)
  pc->test2();

 C ConStack;
 Globaltest(ConStack);

 // will fail because B knows nothing about C
 B BonStack;
 Globaltest(BonStack);
}
Output:

in C
test2 in B
in GlobalTest
Can't cast to C

static_cast 運算符

語法:

static_cast <type-id> (expression)

static_cast 通常用于數(shù)值類型轉(zhuǎn)換,例如枚舉和整型,整型和浮點類型的轉(zhuǎn)換。

在標(biāo)準(zhǔn) C++ 中,static_cast 轉(zhuǎn)換沒有運行時檢測來保證安全性。在 C++/CX 中,則包含了編譯和運行時檢測。

static_cast 運算符能夠用于將基類指針轉(zhuǎn)換為派生類指針,但這樣的轉(zhuǎn)換不總是安全的。

下面還是通過示例進(jìn)行講解。

示例1:

class B {};
class D : public B {};

void f(B* pb, D* pd) {
 D* pd2 = static_cast<D*>(pb); // Not safe, D can have fields
         // and methods that are not in B.

 B* pb2 = static_cast<B*>(pd); // Safe conversion, D always
         // contains all of B.
}

示例1 中 pd2 不為空,當(dāng)用指針 pd2 調(diào)用 B 類型對象不存在的方法或者成員時可能會發(fā)生運行時錯誤(比如調(diào)用虛函數(shù))或者返回非預(yù)期的值。

示例2:

typedef unsigned char BYTE;

void f() {
 char ch;
 int i = 65;
 float f = 2.5;
 double dbl;

 ch = static_cast<char>(i); // int to char
 dbl = static_cast<double>(f); // float to double
 i = static_cast<BYTE>(ch);
}

示例2 中 static_cast 運算符顯示地將內(nèi)置類型進(jìn)行轉(zhuǎn)換。

關(guān)于 static_cast 運算符,還有以下幾種使用情況:

  • static_cast 能夠顯式的將整型轉(zhuǎn)換為枚舉類型。如果整型值不在枚舉值范圍內(nèi),那么返回的枚舉值是未定義的。
  • static_cast 能將任何 expression 顯式地轉(zhuǎn)換為 void 類型。
  • static_cast 操作符不會去除 const,volatile,__unaligned 屬性。

區(qū)分幾種強(qiáng)制轉(zhuǎn)換的使用場景

dynamic_cast 主要用于多態(tài)類型的強(qiáng)制轉(zhuǎn)換,而 static_cast 主要用于非多態(tài)類型的強(qiáng)制轉(zhuǎn)換。

static_cast 轉(zhuǎn)換不像 dynamic_cast 那樣安全。因為 static_cast 沒有運行時檢測。通過 dynamic_cast 進(jìn)行轉(zhuǎn)換時,一旦存在歧義,就會導(dǎo)致失敗,然而 static_cast 會像沒有錯誤發(fā)生一樣返回結(jié)果。盡管 dynamic_cast 更加安全,但 dynamic_cast 僅適用于指針和引用,并且運行時檢測是需要消耗性能的。

示例:

class B {
public:
 virtual void Test(){}
};
class D : public B {};

void f(B* pb) {
 D* pd1 = dynamic_cast<D*>(pb);
 D* pd2 = static_cast<D*>(pb);
}

如果 pb 實際指向類型 D 或者 pd == 0,那么 pd1 和 pd2 將獲得相同的值。

如果 pb 實際指向類型 B,那么 dynamic_cast 會返回 0。但是 static_cast 依賴于 expression 認(rèn)定 pb 指向 D 類型對象,于是簡單的返回 D 類型的指針。

結(jié)果就是,static_cast 轉(zhuǎn)換會繼續(xù)執(zhí)行,但其返回結(jié)果是未定義的。這就需要調(diào)用者去進(jìn)一步驗證轉(zhuǎn)換結(jié)果是有效的。

引用

https://docs.microsoft.com/en-us/cpp/cpp/casting?view=msvc-160

總結(jié)

到此這篇關(guān)于C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++強(qiáng)制轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中結(jié)構(gòu)體和共用體實例教程

    C語言中結(jié)構(gòu)體和共用體實例教程

    這篇文章主要給大家介紹了關(guān)于C語言中結(jié)構(gòu)體和共用體的相關(guān)資料,結(jié)構(gòu)體是一種自定義的復(fù)合數(shù)據(jù)類型,共用體也叫聯(lián)合體,使幾個不同類型的變量共占一段內(nèi)存(相互覆蓋),需要的朋友可以參考下
    2021-06-06
  • C++操作json文件以及jsoncpp配置詳解

    C++操作json文件以及jsoncpp配置詳解

    這篇文章主要給大家介紹了關(guān)于C++操作json文件以及jsoncpp配置的相關(guān)資料,文中通過實例代碼及圖片介紹的非常詳細(xì),需要的朋友可以參考下
    2021-06-06
  • C語言求兩個正整數(shù)的最大公約數(shù)示例代碼

    C語言求兩個正整數(shù)的最大公約數(shù)示例代碼

    在C語言中求兩個數(shù)的最大公約數(shù)是學(xué)習(xí)循環(huán)語句的非常經(jīng)典的問題,下面這篇文章主要給大家介紹了關(guān)于C語言求兩個正整數(shù)的最大公約數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • C++語法中的函數(shù)重載和默認(rèn)參數(shù)

    C++語法中的函數(shù)重載和默認(rèn)參數(shù)

    這篇文章主要介紹了C++語法中的函數(shù)重載和默認(rèn)參數(shù),本文從語法角度通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • C++中delete指針后最好將其置空的操作方法

    C++中delete指針后最好將其置空的操作方法

    C++編程中,當(dāng)你使用delete運算符釋放指針?biāo)赶虻膬?nèi)存后,通常將該指針置空,如果一個指針在被刪除后沒有置空,而你在代碼的其他部分再次嘗試刪除同一個指針,可能會導(dǎo)致程序崩潰或產(chǎn)生未定義行為,本文介紹C++中delete指針后最好將其置空的操作方法,感興趣的朋友一起看看吧
    2024-06-06
  • C語言深入了解函數(shù)

    C語言深入了解函數(shù)

    C語言函數(shù)是用來模塊化構(gòu)建程序的。如果你的功能少,你可以全都寫在mian函數(shù)中,但是當(dāng)實現(xiàn)功能多的時候,如果全寫在main的函數(shù)里,不僅代碼不美觀,而且函數(shù)實現(xiàn)的時候結(jié)構(gòu)復(fù)雜,代碼重復(fù)
    2022-05-05
  • C++迭代器介紹(iterator、const_iterator、reverse_interator、const_reverse_interator)

    C++迭代器介紹(iterator、const_iterator、reverse_interator、const_rev

    這篇文章主要介紹了C++迭代器介紹(iterator、const_iterator、reverse_interator、const_reverse_interator),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • C語言的可變參數(shù)函數(shù)實現(xiàn)詳解

    C語言的可變參數(shù)函數(shù)實現(xiàn)詳解

    某些情況下我們希望函數(shù)的參數(shù)個數(shù)可以根據(jù)需要確定,因此c語言引入可變參數(shù)函數(shù)。典型的可變參數(shù)函數(shù)的例子有printf()、scanf()等,下面我就開始講解
    2021-08-08
  • 詳解C++中普通舊數(shù)據(jù)(POD)的使用

    詳解C++中普通舊數(shù)據(jù)(POD)的使用

    普通舊數(shù)據(jù)就是內(nèi)存中的連續(xù)字節(jié)序列,是能夠被“僅當(dāng)作數(shù)據(jù)”處理的對象。這篇文章主要帶大家了解一下C++中普通舊數(shù)據(jù)的定義與使用,感興趣的可以了解下
    2023-03-03
  • C++之函數(shù)的重載

    C++之函數(shù)的重載

    這篇文章主要介紹了c++函數(shù)重載的相關(guān)知識,文章講解的非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2021-11-11

最新評論

青海省| 祁连县| 鸡泽县| 蒙城县| 天柱县| 临泽县| 深水埗区| 沂南县| 广州市| 乐业县| 汝城县| 博兴县| 金山区| 板桥市| 长武县| 青铜峡市| 轮台县| 文山县| 忻城县| 绥滨县| 长子县| 遵义市| 西丰县| 屏山县| 阿拉善右旗| 凌云县| 鄂伦春自治旗| 明星| 远安县| 石河子市| 马公市| 西林县| 喀什市| 漳州市| 库车县| 安庆市| 横峰县| 介休市| 望江县| 东安县| 桐梓县|