C++的類型轉換

1.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);
}

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

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

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

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

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

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

3.C++強制類型轉換

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

1.static_cast

2.reinterpret_cast

3.const_cast

4.dynamic_cast

3.1 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 用于進行任意類型之間的轉換,包括無關類型之間的轉換。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屬性。const_cast可以修改指針或引用的底層const屬性,但是不能修改常量對象本身的值。它主要用于將const對象轉換為非const對象,以便可以修改其值。

int main()
{//在C++中,volatile是一個關鍵字,用于修飾變量,用來指示編譯器不要進行某些優化,以確//保對該變量的操作在程序執行期間的可見性和有序性。//通常情況下,編譯器會對變量進行各種優化,例如將變量保存在寄存器中以提高訪問//速度,重排代碼以優化執行流程等。然而,對于被volatile修飾的變量,編譯器會在編譯//和優化過程中對其保持謹慎,并生成對其操作的指令,以確保在程序執行期間的可見性和有序性。volatile const int a = 2;int* p = const_cast<int*>(&a);// &a的類型是 const int**p = 3;cout << a << endl;//如果不添加volatile則輸出2,因為編譯器的優化直接把a替換成了2return 0;
}

3.4 dynamic_cast

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

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

向下轉型:父類對象指針/引用->子類指針/引用(用dynamic_cast轉型是安全的)

注意:

1.dynamic_cast只能用于父類含有虛函數的類

2.dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回0

class A
{
public:virtual void f(){}
};class B : public A
{};void fun(A* pa, const string& s)
{cout <<"pa指向"<<s << endl;// dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回B* pb1 = (B*)pa;// 不安全的,因為如果B有自己的成員,那么用指針可以訪問這些成員,但是這個訪問就強制越界了B* pb2 = dynamic_cast<B*>(pa); // 安全的cout << "[強制轉換]pb1:" << pb1 << endl;cout << "[dynamic_cast轉換]pb2:" << pb2 << endl << endl;
}int main()
{A a;B b;fun(&a, "指向父類對象");fun(&b, "指向子類對象");return 0;
}

注意:

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

4.RTTI

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

typeid是C++的一個運算符,用于獲取表達式的類型信息。它的語法形式是typeid(expression),其中expression可以是任何表達式、變量、類型或者類的對象。

typeid運算符返回一個type_info對象,該對象包含有關給定表達式的類型信息。type_info類提供了一些成員函數和操作符,可以用于比較類型信息、獲取類型的名稱等。

typeid運算符的主要用途包括:

  1. 比較類型:可以使用typeid運算符比較兩個類型信息是否相同。如果兩個類型相同(或者是相同類型的派生類),則返回true;否則返回false。示例:
class Base { ... };
class Derived : public Base { ... };Base* base = new Derived();if (typeid(*base) == typeid(Derived)) {// base指向的對象的實際類型是Derived
}
  1. 獲取類型名稱:可以使用type_info對象的name()成員函數獲取類型的名稱,返回一個以NULL結尾的字符串。示例:
class MyClass { ... };MyClass obj;
const std::type_info& type = typeid(obj);
std::cout << type.name() << std::endl; // 輸出類型的名稱

需要注意的是,typeid運算符只能用于在運行時獲取類型信息,而無法獲取模板參數的具體類型。此外,對于沒有多態性的類型或者不完整類型,typeid運算符可能無法正常工作。

另外,為了使用typeid運算符,需要包含頭文件<typeinfo>。

2. dynamic_cast運算符

3. decltype

decltype是C++11引入的一個關鍵字,用于獲取表達式的類型。

decltype的作用包括以下幾個方面:

  1. 推斷表達式的類型:可以使用decltype關鍵字推斷表達式的類型,并將其作為變量的類型或函數返回類型。這在使用模板編程、泛型編程等場景下非常有用,可以根據表達式的結果類型來進行類型推斷。
  2. 保留表達式的修飾符:decltype關鍵字會保留表達式的修飾符,包括const、&和&&等,確保推斷出來的類型與原表達式的類型是一致的。
  3. 支持表達式推斷:decltype關鍵字支持對函數調用、類成員訪問和運算符等復雜表達式進行類型推斷。
  4. 不進行實際計算:decltype關鍵字只進行編譯期的類型推斷,不會對表達式進行實際計算,避免了執行時的開銷。

示例:

int a = 10;
const int& b = a;
decltype(a) c = a; // 推斷c的類型為int
decltype(b) d = b; // 推斷d的類型為const int&
decltype(a + b) e = a + b; // 推斷e的類型為inttemplate<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) { // 推斷函數返回值類型為t + u的類型return t + u;
}

需要注意的是,decltype關鍵字在推斷過程中只使用表達式的類型信息,不會執行任何表達式中的實際計算。此外,如果表達式為變量,而非標識符,則decltype將推斷出變量的引用類型。

5. 常見面試題

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

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

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

相關文章

【機器人最短路徑規劃問題(柵格地圖)】基于模擬退火算法求解

代碼獲取方式&#xff1a;QQ&#xff1a;491052175 或者 私聊博主獲取 基于模擬退火算法求解機器人最短路徑規劃問題&#xff08;柵格地圖&#xff09;的仿真結果 仿真結果&#xff1a; 初始解的路徑規劃圖 收斂曲線&#xff1a; 模擬退火算法求解的路徑規劃圖 結論&#xff…

Ubuntu20安裝zabbix-agent2,對接zabbix 6.4

在Ubuntu 20.04 LTS上安裝Zabbix Agent 2并與Zabbix Server 6.4對接&#xff0c;請按照以下步驟操作&#xff1a; 更新系統&#xff1a; sudo apt update sudo apt upgrade 添加Zabbix官方倉庫&#xff1a; 首先&#xff0c;需要將Zabbix的官方存儲庫添加到你的系統中以獲取Za…

C#面:常用的 異常類 有哪些

異常類是用于處理程序運行時出現的錯誤或異常情況的類。 C# 提供了一些內置的異常類&#xff0c;常用的包括&#xff1a; System.Exception&#xff1a;所有異常類的基類&#xff0c;可以用于捕獲所有類型的異常。System.SystemException&#xff1a;表示系統級別的異常&…

【了解SpringCloud Gateway微服務網關】

曾夢想執劍走天涯&#xff0c;我是程序猿【AK】 目錄 簡述概要知識圖譜什么是SpringCloudGateway功能特征應用場景核心概念配置文件工作原理路由謂詞工廠&#xff08;內置的&#xff09;[After 路由謂詞工廠](https://docs.spring.io/spring-cloud-gateway/docs/current/refere…

Mysql運維篇(七) 部署MHA--完結

一路走來&#xff0c;所有遇到的人&#xff0c;幫助過我的、傷害過我的都是朋友&#xff0c;沒有一個是敵人。如有侵權&#xff0c;請留言&#xff0c;我及時刪除&#xff01; 一、MHA軟件構成 Manager工具包主要包括以下幾個工具&#xff1a; masterha_manger 啟…

【C++】多態深入分析

目錄 一&#xff0c;多態的原理 1&#xff0c;虛函數表與虛函數表指針 2&#xff0c;原理調用 3&#xff0c;動態綁定與靜態綁定 二&#xff0c;抽象類 三&#xff0c;單繼承和多繼承關系的虛函數表 1&#xff0c;單繼承中的虛函數表 2&#xff0c;多繼承中的虛函數表 …

“編碼迷宮中的探險者:探索程序員職業賽道的無限可能“

在這個信息技術飛速發展的時代&#xff0c;程序員的職業賽道就像是一座錯綜復雜的迷宮&#xff0c;它既充滿了挑戰&#xff0c;又蘊藏著無限的機遇。這座迷宮中&#xff0c;有前端的美麗花園&#xff0c;后端的黑暗洞穴&#xff0c;還有數據科學的神秘密室。每一條路徑都有其獨…

內網搭建mysql8.0并搭建主從復制詳細教程!!!

一、安裝mysql 1.1 mysql下載鏈接&#xff1a; https://downloads.mysql.com/archives/community/ 1.2 解壓包并創建相應的數據目錄 tar -xvf mysql-8.2.0-linux-glibc2.28-x86_64.tar.xz -C /usr/local cd /usr/local/ mv mysql-8.2.0-linux-glibc2.28-x86_64/ mysql mkdir…

Python繪圖-9餅圖(上)

餅圖&#xff08;Pie Chart&#xff09;是一種用于表示數據分類和相對大小的可視化圖形。在餅圖中&#xff0c;整個圓形代表數據的總和&#xff0c;而圓形內的各個扇形則代表不同的分類或類別&#xff0c;扇形的面積大小表示該類別在整體中所占的比例。餅圖通常用于展示數據的分…

FW, IPS, IDS

文章目錄 FW (Firewall, 防火墻)IPS (Intrusion Prevention System, 入侵防御系統)IDS (Intrusion Detection System, 入侵檢測系統)IDS vs. FWIPS FW (Firewall, 防火墻) 產品定位&#xff1a; 防火墻的主要作用是進行網絡訪問控制。它充當網絡的門衛&#xff0c;控制進入和離…

《人間值得》讀書筆記

人的一生說短不短&#xff0c;說長不長。蕓蕓眾生&#xff0c;為了生活努力的掙扎&#xff0c;太少的人能衣食無憂&#xff0c;所以我們每天為了碎銀幾兩&#xff0c;為了生活奔波。 《人間值得》的主人公是一個90歲的老奶奶&#xff0c;她的生活經歷很豐富&#xff0c;她的人…

ObjectProvider學習

簡介 ObjectProvider 是 Spring Framework 5.0 之后引入的一個新接口&#xff0c;它提供了一個靈活的方式來訪問由 Spring 容器管理的 Bean。ObjectProvider 提供了一種更加類型安全的方式來查找和注入依賴項&#xff0c;同時還支持 Null 值的處理以及延遲初始化。 ObjectProv…

Window部署Jaeger

參考&#xff1a;windows安裝使用jaeger鏈路追蹤_windows安裝jaeger-CSDN博客 下載&#xff1a;Releases jaegertracing/jaeger GitHub Jaeger – Download Jaeger 目錄 1、安裝nssm 2、安裝運行 elasticsearch 3、安裝運行 3.1部署JaegerAgent 3.2部署JaegerCollec…

【全志D1-H 哪吒開發板】Debian系統安裝調教和點燈指南

全志D1-H開發板【哪吒】使用Deabian系統入門 特別說明&#xff1a; 因為涉及到操作較多&#xff0c;博文可能會導致格式丟失 其中內容&#xff0c;會根據后續使用做優化調整 目錄&#xff1a; 參考資料固件燒錄啟動調教點燈問題 〇、參考資料 官方資料 開發板-D1開發板【…

C++:函數模板整理

函數模板: 找到函數相同的實現思路&#xff0c;區別于函數的參數類型。 使用函數模板使得函數可容納不同類型的參數實現函數功能&#xff0c;而不是當類型不同時便編譯大量類型不同的函數&#xff0c;產生大量重復代碼和內存占用 函數模板格式&#xff1a; template<typ…

[Vulnhub]靶場 Red

kali:192.168.56.104 主機發現 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 …

ARM64匯編02 - 寄存器與指令基本格式

最近的文章可能會有較多修改&#xff0c;請關注博客哦 異常級別 ARMv8處理器支持4種異常等級&#xff08;Exception Level&#xff0c;EL&#xff09;。 EL0 為非特權模式&#xff0c;用于運行應用程序&#xff0c;其他資源訪問受限&#xff0c;權限不夠。 EL1 為特權模式&…

【王道操作系統】ch1計算機系統概述-06虛擬機

文章目錄 【王道操作系統】ch1計算機系統概述-06虛擬機01傳統計算機02虛擬機的基本概念&#xff08;1&#xff09;第一類虛擬機管理程序&#xff08;2&#xff09; 第二類虛擬機管理程序&#xff08;3&#xff09; 兩類虛擬機管理程序的對比 【王道操作系統】ch1計算機系統概述…

效果炸裂、刷爆各大視頻網站的EMO到底是怎么做到的?

文章鏈接&#xff1a;https://arxiv.org/abs/2402.17485 今天分享的工作是刷爆各大視頻平臺的EMO的背后的工作原理。提出的初衷是著手解決增強發言者的頭部特寫視頻生成中的現實感和表現力的挑戰&#xff0c;重點關注音頻提示與面部動作之間的動態和微妙關系。傳統技術具有局限…

【HarmonyOS】鴻蒙開發之Stage模型-UIAbility的啟動模式——第4.4章

UIAbi lity的啟動模式簡介 一共有四種:singleton,standard,specified,multion。在項目目錄的:src/main/module.json5。默認開啟模式為singleton(單例模式)。如下圖 singleton&#xff08;單實例模式&#xff09;啟動模式 每個UIAbility只存在唯一實例。任務列表中只會存在一…