17.C++類型轉換

1. C語言中的類型轉換

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

1.隱式類型轉換:編譯器在編譯階段自動進行,能轉就轉,不能轉就編譯失敗

2.顯時類型轉換:需要用戶自己處理

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


2. 為什么C++需要四種類型轉換

?解決C風格類型轉換的缺陷

C語言中的類型轉換存在以下問題:

  • 缺乏安全性檢查:如父類指針強制轉換為子類指針時,可能指向非子類對象,導致內存越界。
  • 語義模糊:所有轉換都用同一語法(如(int*)),難以區分不同場景(如常量性修改、類層次轉換等),代碼可讀性差。
  • 隱式風險:例如將const指針轉為非const指針,可能導致未定義行為,但編譯器不會警告。

C++要兼容C語言,所以C++還可以使用C語言的轉換風格。

3. C++強制類型轉換

通過四種專用操作符,限制轉換場景并引入安全檢查:

  • static_cast:用于安全的隱式轉換(如基本類型轉換、類層次上行轉換),禁止無關類型轉換(如int*double*)。
  • dynamic_cast:在類層次下行轉換時進行運行時類型檢查(需父類有虛函數),失敗返回nullptr或拋出異常,避免非法訪問。
  • const_cast:明確用于修改constvolatile屬性,避免意外修改常量對象。
  • reinterpret_cast:低級別位模式轉換(如指針轉整數),明確標識高風險操作。

3.1 static_cast

基本類型轉換

double d = 3.14;
int i = static_cast<int>(d);  // 顯式截斷小數部分 

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

以下類型被視為相關類型(Related Types),可安全使用static_cast

  • 同一繼承鏈的類(基類?派生類)
  • 基本數值類型互轉(如intdoublefloatlong
  • 用戶定義轉換支持的類型(通過構造函數或operator重載)
  • void*與其他對象指針(需顯式指明目標類型)

什么叫不相關的類型

  • 無繼承關系:不在同一個類層次結構中(非基類與派生類)。
  • 無標準轉換規則支持:無法通過隱式轉換或用戶定義的轉換函數建立聯系。
  • 內存布局不兼容:類型的大小、對齊方式或二進制表示差異較大。
class A {};
class B {};A* a = new A();
// B* b = static_cast<B*>(a);  // 編譯錯誤:A與B無繼承關系 int x = 10;
int* p = &x;
// double* dp = static_cast<double*>(p);  // 編譯錯誤:int*與double*無關聯 struct Vec3 { float x, y, z; };
// int n = static_cast<int>(Vec3{1,2,3});  // 編譯錯誤:無用戶定義的轉換規則 

3.2 reinterpret_cast

用于將一種類型轉換成另一種不同的類型:

int* p = new int(42);
uintptr_t addr = reinterpret_cast<uintptr_t>(p);  // 地址轉整數 

3.3 const_cast

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

const int x = 10;
int* px = const_cast<int*>(&x);  // 語法允許 
*px = 20;                        // 未定義行為!x可能存儲在只讀內存 

3.4 dynamic_cast

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

dynamic_cast?是 C++ 中**唯一依賴運行時類型信息(RTTI)的類型轉換操作符,專用于處理?類層次結構中的多態類型安全轉換。其核心邏輯為:

  1. 運行時類型檢查:通過查詢對象的虛函數表(vtable)獲取實際類型信息,驗證目標類型是否與對象真實類型兼容。
  2. 安全失敗機制:若轉換不合法(如父類對象并非目標子類實例),指針轉換返回?nullptr,引用轉換拋出?std::bad_cast?異常。
  3. 多態性依賴:要求基類至少有一個虛函數(否則無法生成虛表,編譯報錯)。
class Animal { 
public:virtual ~Animal() {}  // 必須至少有一個虛函數 
};
class Dog : public Animal { 
public: void bark() { /* 子類特有方法 */ } 
};Animal* animal = new Dog();  // 多態指針 
Dog* dog = dynamic_cast<Dog*>(animal);  // 合法:animal實際指向Dog對象 
if (dog) dog->bark();  // 安全調用子類方法 
class A { virtual ~A() {} };
class B : public A {};
class C : public A {};A* obj = new B();
C* c = dynamic_cast<C*>(obj);  // 返回nullptr,因obj實際是B類型 

A類對象obj并非C類實例,而是B類實例

轉換類型典型場景安全檢查性能開銷使用頻率
static_cast類型關聯明確的轉換編譯期檢查????
dynamic_cast多態類型下行轉換運行時檢查較高??
const_cast常量性/易變性修改?
reinterpret_cast底層內存重解釋?

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

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

相關文章

springboot志同道合交友網站設計與實現(代碼+數據庫+LW)

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本志同道合交友網站就是在這樣的大環境下誕生&#xff0c;其可以幫助使用者在短時間內處理完畢龐大的數據信…

VMware中的linux常用指令

常用 Linux 基礎命令 文件與目錄操作 ls&#xff1a;查看當前目錄的文件和子目錄&#xff0c;ls -a顯示所有文件&#xff0c;包括隱藏文件。cd&#xff1a;切換目錄&#xff0c;如 **cd ~** 切換到個人家目錄。pwd&#xff1a;查看當前目錄。mkdir&#xff1a;創建文件夾&#…

20250212:https通信

1:防止DNS劫持:使用 https 進行通信。 因為是SDK授權開發,需要盡量壓縮so庫文件和三方依賴。所以第一想法是使用 head only 的 cpp-httplib 進行開發。 cpp-httplib 需要 SSL 版本是 3.0及以上。但本地已經在開發使用的是1.0.2a版本,不滿足需求。 方案1:升級OpenSSL 將Op…

VisionPro-PMA工具

VisionPro-PMA工具 模板匹配的核心概念 康耐視(Cognex)的VisionPro是一款廣泛應用工業自動化的機器視覺軟件平臺&#xff0c;其模板匹配(Pattern Matching)功能是核心工具之一&#xff0c;常用與目標定位、特征識別和質量檢測等場景。 模板匹配&#xff1a;通過預先定義的參…

2025最新最全【大模型學習路線規劃】零基礎入門到精通_大模型 開發 學習路線

第一階段&#xff1a;基礎理論入門 目標&#xff1a;了解大模型的基本概念和背景。 內容&#xff1a; 人工智能演進與大模型興起。 大模型定義及通用人工智能定義。 GPT模型的發展歷程。 第二階段&#xff1a;核心技術解析 目標&#xff1a;深入學習大模型的關鍵技術和工…

使用CSS3DRenderer/CSS2DRenderer給模型上面添加html標簽

先放一下預覽圖 主要使用css2dRender和css3dRender&#xff0c;添加圖片和標簽。 思路&#xff1a;使用css3dRender添加一個圖片&#xff0c;然后獲取的位置坐標&#xff0c;使用css3dRender添加一個文字標簽&#xff0c;也設置這個位置坐標&#xff0c;此外z軸設置一個高度&a…

完美隱藏滾動條方案 (2024 最新驗證)

完美隱藏滾動條方案 (2024 最新驗證) css /* 全局隱藏豎直滾動條但保留滾動功能 */ html {overflow: -moz-scrollbars-none; /* Firefox 舊版 */scrollbar-width: none; /* Firefox 64 */-ms-overflow-style: none; /* IE/Edge */overflow-y: overlay; …

Linux 內核配置機制詳細講解

本文是對 Linux 內核配置機制 make menuconfig 的 超詳細分步解析&#xff0c;涵蓋其工作原理、界面操作、配置邏輯及底層實現&#xff1a; 一、內核配置系統概述 Linux 內核的配置系統是一個 基于文本的交互式配置工具鏈&#xff0c;核心目標是通過定義 CONFIG_XXX 宏來控制內…

視頻裂變加群推廣分享引流源碼

源碼介紹 視頻裂變加群推廣分享引流源碼 最近網上很火&#xff0c;很多人都在用&#xff0c;適合引流裂變推廣 測試環境&#xff1a;PHP7.4(PHP版本不限制) 第一次訪問送五次觀看次數&#xff0c;用戶達到觀看次數后需要分享給好友或者群,好友必須點擊推廣鏈接后才會增加觀看次…

python-leetcode-每日溫度

739. 每日溫度 - 力扣&#xff08;LeetCode&#xff09; class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:n len(temperatures)answer [0] * nstack [] # 存儲索引for i, temp in enumerate(temperatures):while stack and temperat…

文件下載技術的終極選擇:`<a>` 標簽 vs File Saver.js

文件下載技術的終極選擇&#xff1a;<a> 標簽 vs File Saver.js 在 Web 開發中&#xff0c;文件下載看似簡單&#xff0c;實則暗藏玄機。工作種常糾結于 <a> 標簽的原生下載和 File Saver.js 等插件的靈活控制之間。本文將從原理、優缺點、場景對比到實戰技巧&…

deepseek sse流式輸出

鏈接 semi-ui-vue聊天組件 - 可以用這個組件優化界面 sse服務端消息推送 webflux&webclient Hi-Dream-Blog - 參考這個博客&#xff0c;可以在后臺將markdown語法轉為html 文章目錄 鏈接效果代碼pom.xmlDeepSeekControllerWebConfigDeepSeekClientAiChatRequestAiChatM…

Linux時間日期類指令

1、data指令 基本語法&#xff1a; date &#xff1a; 顯示當前時間date %Y : 顯示當前年份date %m &#xff1a; 顯示當前月份date %d &#xff1a; 顯示當前哪一天date “%Y-%m-%d %H:%M:%S" &#xff1a; 顯示年月日時分秒date -s 字符串時間 &#xff1a; 設置系統時…

SQLMesh 系列教程9- 宏變量及內置宏變量

SQLMesh 的宏變量是一個強大的工具&#xff0c;能夠顯著提高 SQL 模型的動態化能力和可維護性。通過合理使用宏變量&#xff0c;可以實現動態時間范圍、多環境配置、參數化查詢等功能&#xff0c;從而簡化數據模型的開發和維護流程。隨著數據團隊的規模擴大和業務復雜度的增加&…

鵬哥c語言數組(初階數組)

前言&#xff1a; 對應c語言視頻54集 內容&#xff1a; 一維數組的創建 數組是一組相同元素的集合&#xff0c; 數組的創建方式 type_t就是數組的元素類型&#xff0c;const_n是一個常量表達式&#xff0c;用來指定數組的大小 c99標準之前的&#xff0c;數組的大小必須是…

爬蟲運行后如何保存數據?

爬蟲運行后&#xff0c;將獲取到的數據保存到本地或數據庫中是常見的需求。Python 提供了多種方式來保存數據&#xff0c;包括保存為文本文件、CSV 文件、JSON 文件&#xff0c;甚至存儲到數據庫中。以下是幾種常見的數據保存方法&#xff0c;以及對應的代碼示例。 1. 保存為文…

計算機視覺:經典數據格式(VOC、YOLO、COCO)解析與轉換(附代碼)

第一章&#xff1a;計算機視覺中圖像的基礎認知 第二章&#xff1a;計算機視覺&#xff1a;卷積神經網絡(CNN)基本概念(一) 第三章&#xff1a;計算機視覺&#xff1a;卷積神經網絡(CNN)基本概念(二) 第四章&#xff1a;搭建一個經典的LeNet5神經網絡(附代碼) 第五章&#xff1…

linux--多進程基礎(2)GDB多進程調試(面試會問)

將其中的命令記住就行。 總結&#xff1a;GDB下默認調試父進程&#xff0c;可以設置調試父進程還是子進程&#xff0c;也可以設置調試模式&#xff0c;調試模式默認是on即一個在調試另一個直接運行&#xff0c;off就是另一個進程掛起&#xff0c;最后可以查看調試進程 一般默認…

Cramér-Rao界:參數估計精度的“理論底線”

Cramr-Rao界&#xff1a;參數估計精度的“理論底線” 在統計學中&#xff0c;當我們用數據估計一個模型的參數時&#xff0c;總希望估計結果盡可能精確。但精度有沒有一個理論上的“底線”呢&#xff1f;答案是有的&#xff0c;這就是Cramr-Rao界&#xff08;Cramr-Rao Lower …

【復習】Redis

數據結構 Redis常見的數據結構 String&#xff1a;緩存對象Hash&#xff1a;緩存對象、購物車List&#xff1a;消息隊列Set&#xff1a;點贊、共同關注ZSet&#xff1a;排序 Zset底層&#xff1f; Zset底層的數據結構是由壓縮鏈表或跳表實現的 如果有序集合的元素 < 12…