C++進階—C++的類型轉換

第一章:C語言中的類型轉換

在C語言中,如果賦值運算符左右兩側類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發生類型轉化,C語言中總共有兩種形式的類型轉換:隱式類型轉換和顯式類型轉換

  1. 隱式類型轉化:編譯器在編譯階段自動進行,能轉就轉,不能轉就編譯失敗
  2. 顯式類型轉化:需要用戶自己處理
void Test() {int i = 1;// 隱式類型轉換double d = i;printf("%d, %.2f\n", i, d);int* p = &i;// 顯示的強制類型轉換int address = (int)p;printf("%x, %d\n", p, address);
}

缺陷:
轉換的可視性比較差,所有的轉換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉換

第二章:為什么C++需要四種類型轉換

C風格的轉換格式很簡單,但是有不少缺點的:?

  1. 隱式類型轉化有些情況下可能會出問題:比如數據精度丟失
  2. 顯式類型轉換將所有情況混合在一起,代碼不夠清晰

因此C++提出了自己的類型轉化風格,注意因為C++要兼容C語言,所以C++中還可以使用C語言的轉化風格。

第三章:C++強制類型轉換

標準C++為了加強類型轉換的可視性,引入了四種命名的強制類型轉換操作符:
static_cast、reinterpret_cast、const_cast、dynamic_cast

3.1 static_cast

static_cast用于非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可用static_cast,但它不能用于兩個不相關的類型進行轉換

//相近類型用static_cast->意義相似的類型
int main() {double d = 12.34;int a = static_cast<int>(d);cout << a << endl;return 0;
}

3.2 reinterpret_cast

reinterpret_cast操作符通常為操作數的位模式提供較低層次的重新解釋,用于將一種類型轉換為另一種不同的類型

// 有一定的關聯,但是意義不相似的的類型用reinterpret_cast 
int main() {double d = 12.34;int a = static_cast<int>(d);cout << a << endl;// 這里使用static_cast會報錯,應該使用reinterpret_cast//int *p = static_cast<int*>(a);int* p = reinterpret_cast<int*>(a);return 0;
}

3.3 const_cast

const_cast最常用的用途就是刪除變量的const屬性,方便賦值

int main() {const int a = 2;int* p = const_cast<int*>(&a);*p = 3;//當變量被聲明為const時,編譯器會假定它的值永遠不會改變,因此可以進行優化。//在編譯時,編譯器可能會直接用常量值替換所有對a的引用。cout << a << endl;//2 被編譯器優化為直接輸出2cout << *p << endl;//3 實際上訪問了內存中的值//地址相同cout << &a << endl;cout << p << endl;return 0;
}int main() {//告訴編譯器不要優化對該變量的訪問,每次讀取 a 時都必須從內存中重新加載,//而不是使用寄存器中的緩存或直接替換成常量。volatile const int a = 2;int* p = const_cast<int*>(&a);*p = 3;cout << a << endl;//3cout << *p << endl;//3 cout << &a << endl;//012FF93Ccout << p << endl;//012FF93Creturn 0;
}int main() {//使用強制類型轉換與const_cast相同const int a = 2;int* p = (int*)&a;*p = 3;cout << a << endl;//2cout << *p << endl;//3 //地址相同cout << &a << endl;cout << p << endl;return 0;
}

3.4 dynamic_cast

dynamic_cast用于將一個父類對象的指針/引用轉換為子類對象的指針或引用(動態轉換)

向上轉型:子類對象指針/引用->父類指針/引用(不需要轉換,賦值兼容規則)
向下轉型:父類對象指針/引用->子類指針/引用(用dynamic_cast轉型是安全的)

注意:

  1. dynamic_cast只能用于父類含有虛函數的類
  2. dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回0
//必須是多態
class A {
public:virtual void f() {}int _a = 0;
};
class B : public A {
public:int _b = 1;
};//void fun(A* pa) {
//	//向下轉換:直接轉換不完全
//	//fun(&a); 是取a對象的地址,但是被強制轉換為B* 指針后,
//	//會錯誤的以為_a后面還有個_b的成員變量,當取去修改_b時,其實修改的已經不是a對象的空間了
//	B* ptr = (B*)pa;
//	ptr->_a++;
//	ptr->_b++;
//}
void fun(A* pa) {B* ptr = dynamic_cast<B*>(pa);//dynamic_cast的轉換:指向父類轉換失敗,返回空if (ptr) {ptr->_a++;ptr->_b++;cout << ptr->_a << " " << ptr->_b << endl;}else cout << "轉換失敗" << endl;}int main() {//B objb;//A obja = objb;//A& ra = objb;//這里沒有轉換,因為轉換有臨時變量,const引用才可以//向下轉換規則:父類對象不能轉換成子類對象,但父類指針和引用可以轉換為子類的指針和引用A a;B b;fun(&a);//轉換失敗fun(&b);//1 2return 0;
}

注意
強制類型轉換關閉或掛起了正常的類型檢查,每次使用強制類型轉換前,程序員應該仔細考慮是否還有其他不同的方法達到同一目的,如果非強制類型轉換不可,則應限制強制轉換值的作用域,以減少發生錯誤的機會。強烈建議:避免使用強制類型轉換。

第四章:4. RTTI

RTTI:Run-time Type identification的簡稱,即:運行時類型識別。
C++通過以下方式來支持RTTI:

  1. typeid運算符
  2. dynamic_cast運算符
  3. decltype

第五章:常見面試題

1. C++中的4中類型轉化分別是:_________、_________、_________、_________
2. 說說4中類型轉化的應用場景。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917760.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917760.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917760.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Flask的微博話題多標簽情感分析系統設計

基于Flask的微博話題情感分析系統設計與實現 一、項目概述 本項目是一個輕量化的微博話題情感分析系統&#xff0c;通過Flask框架整合情感分析模型&#xff0c;實現對微博話題及評論的情感標簽識別與結果展示。系統面向普通用戶和研究者&#xff0c;提供簡單易用的操作界面&…

TDengine 中 TDgpt 的模型評估工具

模型評估工具 TDgpt 在企業版中提供預測分析模型和異常檢測模型有效性評估工具 analytics_compare&#xff0c;該工具能夠使用 TDengine 中的時序數據作為 回測依據&#xff0c;評估不同預測模型或訓練模型的有效性。該工具在開源版本中不可用使用評估工具&#xff0c;需要在其…

【DL學習筆記】DataLoader類功能和參數說明

文章目錄一、Dataset 與 DataLoader 功能介紹抽象類Dataset的作用DataLoader 作用兩者關系二、torch.utils.data.DataLoader代碼示例常用參數圖示num_workers設置多少合適數據加載子進程如何并行的pin_memorysampler兩種sampler順序采樣 SequentialSampler隨機采樣 RandomSampl…

JVM中年輕代、老年代、永久代(或元空間)、Eden區和Survivor區概念介紹

在Java虛擬機&#xff08;JVM&#xff09;中&#xff0c;內存管理是自動化的&#xff0c;這主要通過垃圾回收機制實現。JVM將堆內存劃分為不同的區域&#xff0c;以便更高效地管理和回收對象。以下是關于年輕代、老年代、永久代&#xff08;或元空間&#xff09;、Eden區和Surv…

譯 | BBC Studios團隊:貝葉斯合成控制方法SCM的應用案例

來自上傳文件中的文章《Using Causal Inference for Measuring Marketing Impact: How BBC Studios Utilises Geo Holdouts and CausalPy》 本篇介紹了在傳統A/B測試不適用時&#xff0c;如何利用貝葉斯合成控制方法和地理區域保留來評估營銷活動效果。其亮點在于通過構建“反事…

Web開發-PHP應用TP框架MVC模型路由訪問模版渲染安全寫法版本漏洞

我們先使用/index.php/index/index/test&#xff0c;就是圖中的test()方法 /index.php/index/index/index&#xff0c;這個回顯就是111 http://127.0.0.1:83/index.php/index/index/test2?x123456 public function test2() {$x$_GET[x];return $x; } 這里再做一個案例更詳細一…

FreeRTOS列表系統深度解析

FreeRTOS列表系統深度解析 一、核心數據結構 1. 列表控制塊 (List_t) typedef struct xLIST {volatile UBaseType_t uxNumberOfItems; // 當前列表項數量ListItem_t * pxIndex; // 遍歷指針&#xff08;用于輪詢調度&#xff09;MiniListItem_t xListEnd; …

《Linux編譯器:gcc/g++食用指南》

堅持用 清晰易懂的圖解 代碼語言&#xff0c;讓每個知識點變得簡單&#xff01; &#x1f680;呆頭個人主頁詳情 &#x1f331; 呆頭個人Gitee代碼倉庫 &#x1f4cc; 呆頭詳細專欄系列 座右銘&#xff1a; “不患無位&#xff0c;患所以立。” 《Linux編譯器&#xff1a;GCC…

SparkKV轉換算子實戰解析

目錄 KV算子 parallelizePairs mapToPair mapValues groupByKey reduceByKey sortByKey 算子應用理解 reduceByKey和groupByKey的區別 groupByKeymapValues實現KV數據的V的操作 改進用reduceByKey groupby通過K和通過V分組的模板代碼 問題集錦 寶貴的經驗 這里會…

深度解析 TCP 三次握手與四次揮手:從原理到 HTTP/HTTPS 的應用

TCP 的三次握手和四次揮手是網絡通信的基石&#xff0c;無論是 HTTP 還是 HTTPS&#xff0c;它們都依賴 TCP 提供可靠的傳輸層服務。本文將用萬字篇幅&#xff0c;結合 Mermaid 圖表和代碼示例&#xff0c;深入講解 TCP 三次握手、四次揮手的原理、過程、狀態變化&#xff0c;以…

Hyper-V + Centos stream 9 搭建K8s集群(一)

一、創建虛擬機一臺32G內存&#xff0c;16核心的Win11&#xff0c;已經安裝了Hyper-V 管理器。然后也下載了CentOS-Stream-9-latest-x86_64-dvd1.iso的鏡像文件。這里Hyper-V創建虛擬機的過程就不贅述了&#xff0c;如果出現虛擬機加載不到鏡像的問題&#xff0c;先把這個使用安…

Pygame如何制作小游戲

以下是 Pygame 的詳細使用指南&#xff0c;從安裝到開發完整游戲的步驟說明&#xff0c;包含代碼示例和最佳實踐&#xff1a; 一、安裝與環境配置 1. 安裝 Pygame pip install pygame2. 驗證安裝 import pygame pygame.init() print(pygame.version.ver) # 應輸出版本號&am…

@【JCIDS】【需求論證】聯合能力集成與開發系統知識圖譜

JCIDS(聯合能力集成與開發系統)知識圖譜 1. JCIDS概述 2. JCIDS的提出背景 3. JCIDS核心流程 4. JCIDS分析方法 5. JCIDS優勢 6. JCIDS與采辦系統的關系 7. JCIDS知識圖譜結構 8. 對我的啟示 9.JCIDS(聯合能力集成與開發系統)相關術語列表 10. 參考文獻 1. JCIDS概述 定義:…

每天學一個Linux命令(38):vi/vim

每天學一個 Linux 命令(38):vi/vim vi 和 vim(Vi IMproved)是 Linux 和 Unix 系統中功能強大的文本編輯器。vim 是 vi 的增強版,提供語法高亮、多級撤銷、插件支持等更多功能。掌握 vi/vim 是 Linux 系統管理員的必備技能之一。 1. 命令簡介 vi:經典的文本編輯器,幾乎…

【PZ-ZU49DR-KFB】:璞致電子 UltraScale+ RFSoC 架構下的軟件無線電旗艦開發平臺

璞致電子 PZ-ZU49DR-KFB 開發板基于 Xilinx ZYNQ UltraScale RFSoC XCZU49DR 主控制器&#xff0c;以 "ARMFPGA 異構架構" 為核心&#xff0c;融合高帶寬信號采集、高速數據處理與靈活擴展能力&#xff0c;專為專業工程師打造的軟件無線電&#xff08;SDR&#xff09…

力扣106:從中序與后序遍歷序列構造二叉樹

力扣106:從中序與后序遍歷序列構造二叉樹題目思路代碼題目 給定兩個整數數組 inorder 和 postorder &#xff0c;其中 inorder 是二叉樹的中序遍歷&#xff0c; postorder 是同一棵樹的后序遍歷&#xff0c;請你構造并返回這顆 二叉樹 。 思路 我們首先要知道中序遍歷和后序…

IDEA JAVA工程入門

Maven配置&#xff1a; IDEA -> settings -> Build, Execution, Deployment -> Build Tools -> MavenMaven home pathUser setting file : 特定倉庫下載依賴包&#xff0c;自動下載(界面右邊M圖標點開&#xff0c;)local repository &#xff08;本地倉庫&#xff…

Spring依賴注入:從原理到實踐的自學指南

Spring依賴注入&#xff1a;從原理到實踐的自學指南 一、什么是依賴注入&#xff1f; 依賴注入&#xff08;Dependency Injection, DI&#xff09;是Spring框架實現控制反轉&#xff08;IoC&#xff09;的核心手段。其核心思想是&#xff1a;對象不再自己創建依賴項&#xff…

3_軟件重構_組件化開發實例方法論

1、上期回顧上次內容核心的地方有兩個&#xff0c;①是C多態基類的指針指向派生類&#xff0c;用于初始化各個插件。②是使用C語言的dlopen函數“動態加載”各個插件&#xff0c;實現用戶根據契約接口自定義開發插件&#xff0c;極大程度地實現了軟件上的解耦。③再進一步&…

C#接口的定義與使用

第1章 接口&#xff08;interface&#xff09;是什么1.1 定義? 接口是一組“能力”或“契約”的抽象描述&#xff0c;只規定“能做什么”&#xff0c;不規定“怎么做”。? 在 C# 中&#xff0c;接口是一種完全抽象的類型&#xff08;fully abstract type&#xff09;。 ? 關…