【重走C++學習之路】26、類型轉換

目錄

一、C語言中的類型轉換

二、C++中的四個類型轉換

2.1 static_cast

2.2 dynamic_cast?

2.3 const_cast?

2.4? reinterpret_cast

2.5 總結?

結語


一、C語言中的類型轉換

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

隱式類型轉換(截斷或提升):

編譯器在編譯階段自動進行,能轉就轉,不能轉就編譯失敗

double pi = 3.14159;
int truncatedPi = pi;  // 隱式轉換,丟失小數部分
printf("Pi: %d\n", truncatedPi);  // 輸出:3
return 0;

隱式轉換可能導致數據丟失:在隱式類型轉換中,可能會將一個較大范圍的數據類型轉換為一個較小范圍的類型,導致數據丟失或精度損失。例如,double?轉換為?int,會丟失小數部分。?

顯式類型轉換(強轉)

用戶自己手動強制轉換變量類型

int num = 100;
int *int_ptr = #
void *void_ptr = (void*)int_ptr;  // 將int指針轉換為void指針
int *new_int_ptr = (int*)void_ptr;  // 再將void指針轉換回int指針

常見場景:

  • 數值類型轉換
  • 指針類型轉換
  • 函數參數類型適配

注意:

  • 數據截斷風險
    在把大范圍的數據類型轉換為小范圍的數據類型(例如從long轉換為int)時,可能會導致數據截斷。
  • 浮點精度丟失
    double類型轉換為float類型時,可能會造成精度的損失。
  • 指針轉換的危險性
    錯誤的指針類型轉換可能會使程序崩潰或者產生未定義行為。

二、C++中的四個類型轉換

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

1. 隱式類型轉化有些情況下可能會出問題:比如數據精度丟失

2. 顯式類型轉換將所有情況混合在一起,代碼不夠清晰

因此C++提出了自己的類型轉換風格,但C++中仍然可以使用C的類型轉換。

在 C++ 里,為了進行類型轉換,提供了四個功能不同的類型轉換運算符,分別是static_castdynamic_castconst_cast以及reinterpret_cast

2.1 static_cast

static_cast主要用于進行良性轉換,非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可用static_cast,但它不能用于兩個不相關的類型進行轉換。它在編譯階段就會完成類型檢查

使用格式:

static_cast<new_type>(expression)

使用場景:

  • 基本數據類型之間的轉換
double d = 3.14;
int i = static_cast<int>(d);  // 把double類型轉換為int類型,值為3
  • 子類到父類的向上轉型
class Base {};
class Derived : public Base {};Derived d;
Base* b = static_cast<Base*>(&d);  // 安全的向上轉型
  • 顯式調用轉換構造函數或者轉換運算符
class Fraction 
{
public:Fraction(int num, int den = 1) : numerator(num), denominator(den) {}operator double() const { return (double)numerator / denominator; }
private:int numerator;int denominator;
};Fraction f(3, 4);
double d = static_cast<double>(f);  // 調用operator double()

2.2 dynamic_cast?

dynamic_cast主要用于進行安全的向下轉型(將父類指針或引用轉換為子類指針或引用),它會在運行時進行類型檢查。如果轉換不安全,對于指針會返回nullptr,對于引用則會拋出std::bad_cast異常。

使用格式:

dynamic_cast<new_type>(expression)

使用場景:

  • 安全的向下轉型
class Base { virtual void dummy() {} };  // 必須有虛函數,才能進行RTTI
class Derived : public Base {};Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b);  // 轉換成功,d不為nullptr
  • 交叉轉型?
class Base { virtual void dummy() {} };
class Derived1 : public Base {};
class Derived2 : public Base {};
class Derived3 : public Derived1, public Derived2 {};Derived3* d3 = new Derived3;
Derived1* d1 = dynamic_cast<Derived1*>(d3);  // 轉換成功
Derived2* d2 = dynamic_cast<Derived2*>(d1);  // 交叉轉型,d2不為nullptr

2.3 const_cast?

const_cast專門用于修改類型的constvolatile屬性,主要用于去除const限定(但要注意,通過這種方式修改原本為const的對象是未定義行為)。

使用格式:

const_cast<new_type>(expression)

使用場景:

  • 去除函數參數的const屬性
void print(char* str) 
{printf("%s\n", str);
}const char* cstr = "Hello";
char* str = const_cast<char*>(cstr);  // 去除const限定
// print(cstr);  // 錯誤:不能將const char*傳遞給char*
print(str);     // 正確
  • const成員函數中修改對象狀態
class Counter 
{
public:void increment() const {// count++;  // 錯誤:在const成員函數中不能修改成員變量const_cast<int&>(count)++;  // 正確:去除const限定}
private:int count;
};

2.4? reinterpret_cast

reinterpret_cast用于進行低級的類型重新解釋,比如將指針轉換為整數,或者將一種類型的指針轉換為另一種不相關類型的指針。

使用格式:

reinterpret_cast<new_type>(expression)

使用場景:

  • 指針和整數之間的轉換?
int* ptr = new int(10);
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);  // 將指針轉換為整數
int* new_ptr = reinterpret_cast<int*>(addr);  // 將整數轉換回指針
  • 不相關類型指針之間的轉換
int num = 10;
int* int_ptr = &num;
char* char_ptr = reinterpret_cast<char*>(int_ptr);  // 將int指針轉換為char指針
  • 函數指針類型的轉換
typedef void (*FuncPtr)();int add(int a, int b) 
{ return a + b; 
}FuncPtr func = reinterpret_cast<FuncPtr>(add);  // 函數指針類型轉換
// func();  // 調用會導致未定義行為

2.5 總結?

轉換運算符主要用途安全性
static_cast基本類型轉換、向上 / 向下轉型(不進行運行時檢查)中等
dynamic_cast安全的向下轉型、交叉轉型(運行時類型檢查)
const_cast修改const/volatile屬性低(容易導致未定義行為)
reinterpret_cast低級指針類型重新解釋、指針與整數轉換極低(非常危險)

結語

在實際編程中,優先使用C++風格的類型轉換,避免使用C風格的強制類型轉換,提高代碼的安全性和可讀性,這種用法會在Linux編程中見到。

下一篇將會介紹C++中IO流相關的知識,可以看作文件操作,有興趣的朋友可以關注一下。

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

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

相關文章

kotlin 過濾 filter 函數的作用和使用場景

1. filter 函數的作用 filter 是 Kotlin 集合操作中的一個高階函數&#xff0c;用于根據指定條件從集合中篩選出符合條件的元素。 作用&#xff1a;遍歷集合中的每個元素&#xff0c;并通過給定的 lambda 表達式判斷是否保留該元素。返回值&#xff1a;一個新的集合&#xff…

安卓程序打包與發布

一 配置編譯信息 二 創建密鑰

LeetCode算法題 (移除鏈表元素)Day15!!!C/C++

https://leetcode.cn/problems/remove-linked-list-elements/description/ 一、題目分析 給你一個鏈表的頭節點 head 和一個整數 val &#xff0c;請你刪除鏈表中所有滿足 Node.val val 的節點&#xff0c;并返回 新的頭節點 。 今天的題目非常好理解&#xff0c;也就是要刪除…

Scrapy框架之【Scrapy-Redis】分布式爬蟲詳解

Scrapy-Redis 介紹 Scrapy-Redis 是一個基于 Redis 實現的 Scrapy 分布式爬蟲組件。Scrapy 本身是一個強大的 Python爬蟲框架&#xff0c;但它默認是單進程單線程的&#xff0c;在面對大規模數據抓取任務時效率不高。Scrapy-Redis 則解決了這一問題&#xff0c;它允許你將 Scra…

Gradio全解20——Streaming:流式傳輸的多媒體應用(3)——實時語音識別技術

Gradio全解20——Streaming&#xff1a;流式傳輸的多媒體應用&#xff08;3&#xff09;——實時語音識別技術 本篇摘要20. Streaming&#xff1a;流式傳輸的多媒體應用20.3 實時語音識別技術20.3.1 環境準備和開發步驟1. 環境準備2. ASR應用開發步驟&#xff08;基于Transform…

使用xlwings將兩張順序錯亂的表格進行數據核對

有如下一個excel表&#xff0c;姓名列的內容相同&#xff0c;順序不同&#xff1b;月薪有部分內容不同。 目的&#xff1a;要找出哪幾條月薪不同。 通常的做法&#xff0c;要使用excel的高級篩選。 在此&#xff0c;使用xlwings實現&#xff0c;在不同的內容上涂色。 代碼如…

2025大模型安全研究十大框架合集(10份)

2025大模型安全研究十大框架合集的詳細介紹&#xff1a; Anthropic AI信任研究框架 Anthropic于2024年10月更新的《安全責任擴展政策》(RSP)&#xff0c;提出了一個靈活的動態AI風險治理框架。該框架規定當AI模型達到特定能力時&#xff0c;將自動升級安全措施&#xff0c;如…

Qt/C++開發監控GB28181系統/云臺控制/獲取預置位信息/添加刪除調用預置位

一、前言 之前用onvif已經完美實現了設備的云臺控制和預置位的功能&#xff0c;這個基礎功能在監控系統中是使用頻率很高的&#xff0c;所有gb28181肯定也提供了這樣的功能&#xff0c;很多人以為是通過包含xml數據&#xff0c;對應節點指定對應的動作來實現&#xff0c;其實不…

第T8周:貓狗識別

● 語言環境&#xff1a;Python3.8.8 ● 編譯器&#xff1a;Jupyter Lab ● 深度學習環境&#xff1a;TensorFlow2.4.1 貓狗識別 一、前期工作1. 設置GPU 二、數據預處理1. 加載數據2.再次檢查數據3.配置數據集 三、構建VG-16網絡四、編譯五、訓練模型六、模型評估七、預測八、…

主流微前端框架比較

主流微前端框架比較 以下表格列出了當前主流微前端框架的核心對比信息,包括基本介紹、核心特性、適用場景、技術棧兼容性、優缺點、社區維護情況和典型應用案例等: 框架基本介紹核心特性與機制適用場景技術棧兼容性優缺點社區維護情況典型應用案例qiankun螞蟻金服推出的生產…

大學生入學審核系統設計與實現【基于SpringBoot + Vue 前后端分離技術】

一、項目概述 1.1 項目背景 隨著高校的不斷擴招&#xff0c;傳統的入學審核管理模式已不能滿足大規模學生數據的處理需求。人工管理不僅效率低下&#xff0c;還容易出現疏漏。本系統通過信息化手段&#xff0c;提升入學審核過程中的數據管理和審批效率。 1.2 系統目標 系統…

云計算-容器云-服務網格Bookinfo

服務網格&#xff1a;創建 Ingress Gateway 將 Bookinfo 應用部署到 default 命名空間下&#xff0c;請為 Bookinfo 應用創建一個網 關&#xff0c;使外部可以訪問 Bookinfo 應用。 上傳ServiceMesh.tar.gz包 [rootk8s-master-node1 ~]# tar -zxvf ServiceMesh.tar.gz [rootk…

Spring 分批處理 + 冷熱數據分離:歷史訂單高效遷移與數據清理實戰

在實際業務中&#xff0c;隨著時間推移&#xff0c;訂單量持續增長&#xff0c;若未及時進行數據治理&#xff0c;會造成數據庫膨脹、查詢緩慢、性能下降等問題。為了實現數據分層管理和系統高性能運行&#xff0c;我們在項目中采用了“冷熱數據分離 分批遷移 數據清理”的綜…

新手SEO優化核心步驟

內容概要 對于SEO新手而言&#xff0c;建立系統化的優化框架是突破入門瓶頸的關鍵。SEO的核心在于通過技術手段與內容策略的結合&#xff0c;提升網站在搜索引擎中的可見性與用戶價值。具體而言&#xff0c;新手需優先掌握關鍵詞研究&#xff0c;明確目標用戶的搜索意圖&#…

C++ 之 【list的簡介、list 的構造函數、iterator、容量操作、元素訪問、增刪查改與迭代器失效】

目錄 1.list的介紹 2.list的使用 2.1 構造函數 2.2 iterator 的使用 2.3 容量操作 2.4 元素訪問 2.5 增刪查改 2.5.1頭插頭刪與尾插尾刪 2.5.2 insert 、erase 函數 2.5.3 clear、swap函數 2.5.4 關于find函數 3.迭代器失效 1.list的介紹 (1)list的底層通常實現為帶…

Laravel Octane 項目加速與靜態資源優化指南

Laravel Octane 項目加速與靜態資源優化指南 一、Octane 核心加速配置 擴展安裝與環境配置 composer require laravel/octane # 安裝核心擴展?php artisan octane:install # 生成配置文件&#xff08;選擇 Swoole/RoadRunner 等服務器&#xff09;?服務器參數調優? …

高露潔牙膏是哪個國家的品牌?高露潔牙膏哪一款最好?

高露潔是來自于美國一個比較有知名度的品牌&#xff0c;在1806年的時候創立。總部是在美國紐約公園大道&#xff0c;在1873年時&#xff0c;高露潔就已經開始銷售罐裝牙膏。 在1896年時期推出可折疊管牙膏&#xff0c;在口腔護理產品發展的過程中擁有著不容忽視的地位。在1992…

【Python爬蟲詳解】第八篇:突破反爬體系的工程實踐

當矛與盾的較量進入白熱化&#xff0c;突破反爬需要的不只是技巧&#xff0c;更是一套完整的工程化解決方案——本文將揭示對抗現代反爬體系的九大核心戰術。 一、JavaScript混淆的深度破解 1. AST&#xff08;抽象語法樹&#xff09;解混淆 案例&#xff1a;某電商平臺商品價…

【Linux調整FTP端口】

Linux調整FTP端口 一、確保新端口未被占用在修改端口之前&#xff0c;可以使用以下命令檢查端口是否被占用&#xff1a; 二、修改vsftpd配置文件1. 打開vsftpd配置文件2. 找到并修改端口配置3. 保存并退出4. 重啟vsftpd服務 三、配置防火墻 在Linux系統中修改FTP端口&#xff0…

npm打包內存不足- JavaScript heap out of memory

直接貼出報錯信息 <--- Last few GCs --->[30904:0000010F60FE58E0] 22090 ms: Scavenge 2037.4 (2069.4) -> 2036.4 (2074.2) MB, 2.5 / 0.0 ms (average mu 0.228, current mu 0.216) allocation failure [30904:0000010F60FE58E0] 22101 ms: Scavenge 2…