成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換講解-創(chuàng)新互聯(lián)

本篇內(nèi)容主要講解“C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換講解”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換講解”吧!

我們注重客戶提出的每個(gè)要求,我們充分考慮每一個(gè)細(xì)節(jié),我們積極的做好成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)服務(wù),我們努力開(kāi)拓更好的視野,通過(guò)不懈的努力,成都創(chuàng)新互聯(lián)公司贏得了業(yè)內(nèi)的良好聲譽(yù),這一切,也不斷的激勵(lì)著我們更好的服務(wù)客戶。 主要業(yè)務(wù):網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),小程序制作,網(wǎng)站開(kāi)發(fā),技術(shù)開(kāi)發(fā)實(shí)力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫(kù)的技術(shù)開(kāi)發(fā)工程師。

引言

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

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

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

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

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

  • dynamic_cast

  • static_cast

  • const_cast

  • reinterpret_cast

  • safe_cast


本文會(huì)著重介紹如何使用 dynamic_cast 和 static_cast。

提醒:

除非必須,不要使用 const_cast 和 reinterpret_cast,因?yàn)樗鼈兇嬖谝恍├鲜?C 語(yǔ)言轉(zhuǎn)換中的隱患。

dynamic_cast 運(yùn)算符

語(yǔ)法:

 dynamic_cast <type-id> (expression)

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

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

如非需要,現(xiàn)代 C++ 中應(yīng)該避免使用 void 指針,因?yàn)槿菀壮鲥e(cuò)。

下面看些示例,了解 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 中提到了子對(duì)象(subobject)的概念,注意與子類型進(jìn)行區(qū)分:

  • Root 類型包含子類型 Base,Base 類型包含子類型 Derived。

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


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

示例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 中 通過(guò) dynamic_cast 轉(zhuǎn)換為 pd2 時(shí),不會(huì)報(bào)錯(cuò),返回 nullptr。但如果同樣地情況轉(zhuǎn)換的對(duì)象是引用類型,那么運(yùn)行時(shí)會(huì)拋出 std::bad_cast 異常。如果 pb2 指向/引用的對(duì)象無(wú)效,同樣也會(huì)拋出異常。

示例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 運(yùn)算符

語(yǔ)法:

static_cast <type-id> (expression)

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

在標(biāo)準(zhǔn) C++ 中,static_cast 轉(zhuǎn)換沒(méi)有運(yùn)行時(shí)檢測(cè)來(lái)保證安全性。在 C++/CX 中,則包含了編譯和運(yùn)行時(shí)檢測(cè)。

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

下面還是通過(guò)示例進(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 類型對(duì)象不存在的方法或者成員時(shí)可能會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤(比如調(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 運(yùn)算符顯示地將內(nèi)置類型進(jìn)行轉(zhuǎn)換。

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

  • static_cast 能夠顯式的將整型轉(zhuǎn)換為枚舉類型。如果整型值不在枚舉值范圍內(nèi),那么返回的枚舉值是未定義的。

  • static_cast 能將任何 expression 顯式地轉(zhuǎn)換為 void 類型。

  • static_cast 操作符不會(huì)去除 const,volatile,__unaligned 屬性。


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

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

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

示例:

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 實(shí)際指向類型 D 或者 pd == 0,那么 pd1 和 pd2 將獲得相同的值。

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

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

總結(jié)

到此,相信大家對(duì)“C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換講解”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)建站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

分享題目:C++基礎(chǔ)入門篇之強(qiáng)制轉(zhuǎn)換講解-創(chuàng)新互聯(lián)
當(dāng)前URL:http://jinyejixie.com/article14/dpsdge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣小程序開(kāi)發(fā)、網(wǎng)站內(nèi)鏈、做網(wǎng)站、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
宣威市| 镇雄县| 东宁县| 巴南区| 刚察县| 芒康县| 获嘉县| 汽车| 许昌市| 昭平县| 克拉玛依市| 常山县| 双流县| 台山市| 巴南区| 临湘市| 安仁县| 沙洋县| 衡南县| 当阳市| 沂源县| 沁水县| 迁西县| 吴堡县| 宿州市| 台州市| 镇原县| 电白县| 秀山| 英德市| 疏附县| 安达市| 县级市| 盘山县| 衡阳市| 璧山县| 和政县| 太谷县| 龙江县| 长兴县| 江阴市|