C++類型轉換詳解

目錄

一、內置 轉 內置

二、內置 轉 自定義

三、自定義 轉 內置

四、自定義 轉 自定義

五、類型轉換規范化

1.static_case

2.reinterpret_cast

3.const_cast

4.dynamic_cast

六、RTTI


一、內置 轉 內置

????????C++兼容C語言,在內置類型之間轉換規則和C語言一樣的,C/C++語言因為允許類型轉換所以不是類型安全的語言。

隱式轉化:編譯器識別出類型不同后,能轉就轉,不能轉則報錯。

例如:

  • int = 'a'?
  • char = 4
  • int = 8.26

除此之外函數調用中形參和實參的類型不同時,編譯器會嘗試進行隱式轉化。

顯示轉化(強制類型轉化):用戶進行指定的顯示轉換。

例如:

  • int = (int)'a'?
  • char = (char)4
  • int = (int)8.26

什么時候能轉什么時候不能轉呢?

????????通常有關聯性的類型,有轉換意義的類型都是可以轉化的。比如int類型與double類型,float類型,short類型等,都是描述數字的大小,又或者各種指針類型之間。

? ? ? ? 又比如int與指針不能隱式轉換,因為轉化后也是無意義的。但可以顯示轉化(強制類型轉化)。

二、內置 轉 自定義

????????c++中支持內置類型轉自定義類型,只需要提供相應的構造函數,就可以想怎么轉就怎么轉,全在于你的構造函數怎么實現。如下:

using namespace std;
class A
{
public:A(int x):a(x),b(x){}A(int x,int y,int z):a(x), b(y+z){}
private:int a;int b;
};
void fun(A x)
{//......
}
int main()
{int v = 10;A a1 = v;//int類型隱式轉化為A類型A a2 = { 1,2,3 };fun(6);return 0;
}
  • A a1 = v:調用構造函數產生臨時對象,然后調用拷貝賦值。邏輯上是這樣,但實際上會被編譯器優化。
  • A a2 = {1,2,3}:通過花括號傳入多個參數構造臨時對象,然后調用拷貝賦值。
  • ?fun(6):在函數傳參時,同樣會隱式轉換,不用單獨構造出類型后傳入,這樣就顯得方便得多。

在構造函數的函數名前加關鍵字explicit:不被允許隱式轉換,要進行轉換需要顯示的進行。

三、自定義 轉 內置

????????c++中支持自定義類型轉內置類型,提供相應的運算符重載函數(operator),同樣可以想怎么轉就怎么轉,都是自己設定的。

????????強制類型轉化的運算符是(),按理來說應該重載()運算符,但是又與仿函數沖突,所以c++制定了特殊的函數來做類型轉化,即:

  • operator 類型 ()

該函數不用寫返回類型,但在函數名后面需要加目標類型,函數結束也需要return返回。

class A
{
public:A(int x,int y):_a(x),_b(y){}operator int(){return _a + _b;}
private:int _a;int _b;
};
int main()
{A a1 = { 1,3 };int x = a1;return  0;
}

同樣可以使用explicit修飾,修飾后不支持隱式轉化。

????????比如在c++智能指針shared_ptr中使用了operator bool()把指針轉換為bool類型來判斷指針是否為空,如下:

測試如下:

#include <iostream>
#include <memory>
using namespace std;
int main()
{shared_ptr<int> p(new int(10));if (!p)//隱式轉換為bool類型cout << "p為nullptr";else cout << "p不為nullptr";return 0;
}

四、自定義 轉 自定義

????????c++中自定義與自定義之間同樣可以轉換,核心是讓構造函數產生臨時對象。比如我們要讓B類型轉換為A類型,我們可以構造這樣一個函數:

class A
{
public:A(int x):_a(x),_b(x){}int get_a(){return _a;}
private:int _a;int _b;
};
class B
{
public:B(A x):_val(x.get_a()){}
private:int _val;
};
int main()
{A a = 4;B b = a;return  0;
}

五、類型轉換規范化

????????C 風格的類型轉換過于“暴力”,允許許多不安全的轉換。C++提供的?顯式類型轉換運算符來替代傳統的 C 風格強制類型轉換(如?(int)x)。這種機制的目的是提高代碼的?類型安全性可讀性?和?維護性,同時限制不安全的隱式轉換。

它有四種類型轉換運算符,接下來我們依次來學習。

1.static_case

????????用于意義相近的轉換,比如int與double,char與int,左值與右值,如下:

int main()
{char ch = 'm';int x = static_cast<int>(ch);return 0;
}

2.reinterpret_cast

????????reinterpret_cast用于高風險的類型轉換,即意義不相近的類型之間,或各種指針之間的轉換,比如int與int*,char*與int*。

int main()
{int x = 10;int* p = reinterpret_cast<int*>(x);return 0;
}

3.const_cast

????????const_cast用來添加/移除const屬性的類型間轉換,或者添加/移除volatile屬性的類型間轉換,如下:

int main()
{volatile const int n = 10;int* v = const_cast<int*>(&n);//移除const屬性const int& m = const_cast<const int&>(m);//移除volatile屬性return 0;
}

4.dynamic_cast

用于基類與派生類之間的類型轉換。

????????派生類轉基類也叫切片,天然就可以實現的,但是基類轉派生類可能會存在越界訪問的問題。用這個關鍵字可以有效避免。

class Base { 
public:virtual ~Base() {} 
};
class Derived : public Base {};Base* base_ptr = new Base(); // 基類指針指向基類對象// 嘗試向下轉型
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
if (derived_ptr == nullptr) { // 轉換失敗!
}

六、RTTI

????????RTTI(Runtime Type Information,運行時類型信息)?是 C++ 提供的一種在程序運行時獲取對象類型信息的機制。它允許程序在運行時檢測對象的實際類型,并支持安全的類型轉換(如?dynamic_cast)和類型查詢(如?typeid)。

????????注意:typeid并不是每次都是運行時類型識別。RTTI依賴多態類型,只有類有虛函數時才能體現?。

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

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

相關文章

QEMU源碼全解析 —— 塊設備虛擬化(17)

接前一篇文章:QEMU源碼全解析 —— 塊設備虛擬化(16) 本文內容參考: 《趣談Linux操作系統》 —— 劉超,極客時間 《QEMU/KVM源碼解析與應用》 —— 李強,機械工業出版社 《KVM實戰 —— 原理、進階與性能調優》—— 任永杰 程舟,機械工業出版社

mac 卸載流氓軟件安全助手

之前個人電腦在公司使用過一段時間&#xff0c;為了使用網線聯網安裝了公司指定的 聯軟上網助手&#xff0c;誰知安裝容易卸載難&#xff0c;后來找運維來卸載&#xff0c;輸入管理員密碼后&#xff0c;也無反應&#xff0c;最后不了了之了&#xff0c;這個毒瘤軟件長期在后臺駐…

Java 大視界 -- Java 大數據機器學習模型在智能客服多輪對話系統中的優化策略(179)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

極氪汽車云原生架構落地實踐

云原生架構落地實踐的背景 隨著極氪數字業務的飛速發展&#xff0c;背后的 IT 技術也在不斷更新迭代。極氪極為重視客戶對服務的體驗&#xff0c;并將系統穩定性、業務功能的迭代效率、問題的快速定位和解決視為構建核心競爭力的基石。 為快速響應用戶的需求&#xff0c;例如…

Python?判斷循環

????˙?˙? ? 判斷??常用的判斷符號(比較運算符)andor括號notin 和 not inif-elif-else循環??計數循環 forrange()函數簡易倒計時enumerate()函數zip()函數遍歷列表遍歷元組遍歷字符串遍歷字典條件循環 while提前跳轉 continue跳出循環 break能量站??判斷?? …

FreeRTOS與RT-Thread深度對比:從入門到精通的全面解析

FreeRTOS與RT-Thread深度對比&#xff1a;從入門到精通的全面解析 在嵌入式系統開發領域&#xff0c;實時操作系統(RTOS)扮演著至關重要的角色。FreeRTOS和RT-Thread作為兩款主流的開源RTOS&#xff0c;各有特色&#xff0c;適用于不同的應用場景。本文將從小白到大神的角度&a…

OpenCV 圖形API(18)用于執行兩個矩陣(或數組)的逐元素減法操作函數sub()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 描述 計算兩個矩陣之間的逐元素差值。 sub 函數計算兩個矩陣之間的差值&#xff0c;要求這兩個矩陣具有相同的尺寸和通道數&#xff1a; dst ( I ) src…

LeetCode刷題SQL筆記

系列博客目錄 文章目錄 系列博客目錄1.distinct關鍵字 去除重復2.char_length()3.group by 與 count()連用4.date類型有個函數datediff()5.mod 函數6.join和left join的區別1. **JOIN&#xff08;內連接&#xff0c;INNER JOIN&#xff09;**示例&#xff1a; 2. **LEFT JOIN&a…

其他合成方式介紹

在 SurfaceFlinger 的 Layer 處理邏輯中&#xff0c;除了常見的 Client Composition&#xff08;GPU合成&#xff09; 和 Device Composition&#xff08;HWC合成&#xff09;&#xff0c;還存在一些特殊的合成方式&#xff0c;比如 Sideband、Solid Color 和 Display Decorati…

GraphRAG與知識圖譜

一、GraphRAG介紹 1.1 什么是 Graph RAG&#xff1f; Graph RAG&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;是一種基于知識圖譜的檢索增強技術&#xff0c; 通過構建圖模型的知識表達&#xff0c;將實體和關系之間的聯系用圖的形式進行展示&#xff…

一個開源的 VS Code 大模型聊天插件:Light-at

這篇文章是一個開發雜談。對于有經驗的開發者來說&#xff0c;可能這個項目并不算特別復雜或者高技術&#xff0c;只是對我個人來說算一個里程碑&#xff0c;因此寫篇雜談文章記錄一下。也許也能給起步者一些參考。 項目地址&#xff1a;https://github.com/HiMeditator/light-…

SQL121 創建索引

-- 普通索引 CREATE INDEX idx_duration ON examination_info(duration);-- 唯一索引 CREATE UNIQUE INDEX uniq_idx_exam_id ON examination_info(exam_id);-- 全文索引 CREATE FULLTEXT INDEX full_idx_tag ON examination_info(tag);描述 現有一張試卷信息表examination_in…

【Pandas】pandas DataFrame set_flags

Pandas2.2 DataFrame Attributes and underlying data 方法描述DataFrame.index用于獲取 DataFrame 的行索引DataFrame.columns用于獲取 DataFrame 的列標簽DataFrame.dtypes用于獲取 DataFrame 中每一列的數據類型DataFrame.info([verbose, buf, max_cols, …])用于提供 Dat…

Linux終止進程(kill process)的一些玩法

經常運行一個程序時&#xff0c;表面上已經終止了&#xff0c;實際上還在后臺運行。一來呢&#xff0c;它可能占據端口&#xff0c;導致端口復用的時候報錯。二來呢&#xff0c;它可能占用GPU&#xff0c;讓你顯存直接少一塊。 尤其是在多進程程序&#xff0c;假如運行“python…

《比特城傳奇:公鑰、私鑰與網絡安全的守護之戰》

點擊下面圖片帶您領略全新的嵌入式學習路線 &#x1f525;爆款熱榜 88萬閱讀 1.6萬收藏 第一章&#xff1a;雙鑰之謎 比特城的清晨總是籠罩著一層薄霧&#xff0c;仿佛這座城市本身就是由無數個0和1編織而成的幻境。在這里&#xff0c;信息如同空氣般無處不在&#xff0c;但…

BGP路由協議之屬性1

公認屬性是所有 BGP 路由器都必須能夠識別的屬性 公認必遵 (Well-known Mandatory) : 必須包括在每個 Update 消息里公認任意 (Well-known Discretionary) : 可能包括在某些 Update 消息里。 可選屬性不需要都被 BGP 路由器所識別 可選過渡(OptionalTransitive) : BGP 設備不…

Pr視頻剪輯 Premiere Pro 2024 for Mac

Pr視頻剪輯 Premiere Pro 2024 for Mac 文章目錄 Pr視頻剪輯 Premiere Pro 2024 for Mac一、介紹二、效果三、下載 一、介紹 Premiere Pro 2024 for Mac是一款專業的視頻編輯軟件&#xff0c;廣泛應用于電影、電視、廣告等領域。它為Mac用戶提供了強大的剪輯、調色、音頻處理等…

oracle 包的管理

在PL/SQL程序開發中&#xff0c;為了方便實現模塊化程序的管理&#xff0c;可以將PL/SQL元素&#xff08;如存儲過程、函數、變量、常量、自定義數據類型、游標等&#xff09;根據模塊的程序結構組織在一起&#xff0c;存放在一個包中&#xff0c;稱為一個完整的單元&#xff0…

LINUX 5 cat du head tail wc 計算機拓撲結構 計算機網絡 服務器 計算機硬件

計算機網絡 計算機拓撲結構 計算機按性能指標分&#xff1a;巨型機、大型機、小型機、微型機。大型機、小型機安全穩定&#xff0c;小型機用于郵件服務器 Unix系統。按用途分&#xff1a;專用機、通用機 計算機網絡&#xff1a;局域網‘、廣域網 通信協議’ 計算機終端、客戶端…

從零開始的圖論講解(1)——圖的概念,圖的存儲,圖的遍歷與圖的拓撲排序

目錄 前言 圖的概念 1. 頂點和邊 2. 圖的分類 3. 圖的基本性質 圖的存儲 鄰接矩陣存圖 鄰接表存圖 圖的基本遍歷 拓撲排序 拓撲排序是如何寫的呢? 1. 統計每個節點的入度 2. 構建鄰接表 3. 將所有入度為 0 的節點加入隊列 4. 不斷彈出隊頭節點&#xff0c;更新其…