【c++】四種類型轉換形式

【c++】四種類型轉換形式

編譯時:
static_cast(靜態轉換)
const_cast(去常性轉換)
reinterpret_cast(重新解釋轉換,直接轉換地址)
運行時:
dynamic_cast(動態轉換,運行時類型識別 RTTI)


static_cast(靜態轉換)

用途描述注意事項
基本數據類型之間的轉換用于 intdoublecharint 等類型之間的轉換。適用于已知類型的轉換,比 C 風格轉換更安全。
void* 轉換為其他類型用于將 void* 指針還原為具體類型的指針。必須確保指針類型正確,避免未定義行為。
左值轉換為右值用于將左值轉換為右值引用,常用于移動語義。強制轉換為右值引用,觸發移動構造。
類型層次結構中的指針和引用轉換在類繼承關系中,用于基類和派生類之間的轉換。只能進行安全的向上轉換,向下轉換需要 dynamic_cast
int 類型轉換為枚舉允許 int 與枚舉類型之間的轉換。適用于整數到枚舉的安全轉換。
static_cast 在模板中的應用用于確保目標類型和原始類型一致,并在模板編程中進行類型轉換。使用 static_assert 進行編譯期類型檢查。

1. 基本數據類型轉換

static_cast 可用于基本數據類型之間的轉換,如 intdoublecharint,等價于 C 風格轉換,但更安全。

#include <iostream>int main() {double d = 3.14159;int i = static_cast<int>(d);  // 截斷小數部分,轉換為 3char c = 'A';int ascii = static_cast<int>(c);  // 將字符 'A' 轉換為 ASCII 碼std::cout << "i = " << i << ", ascii = " << ascii << std::endl;return 0;
}

? 優點:比 C 風格轉換更安全,可讀性更好,避免了 reinterpret_cast 的風險。


2. void* 轉換為其他類型

static_cast 可以用于void* 還原為具體類型,但必須確保指針類型正確,否則可能導致未定義行為。

#include <iostream>int main() {int a = 42;void* pVoid = &a;  // int* → void*int* pInt = static_cast<int*>(pVoid);  // void* → int*std::cout << "pInt = " << *pInt << std::endl;return 0;
}

? 適用于已知原始類型的情況,如果不確定類型,應使用 reinterpret_cast


3. 左值轉換為右值

在 C++11 及更高版本中,static_cast 可以將左值轉換為右值引用,用于移動語義

#include <iostream>
#include <utility>  // std::moveclass Data {
public:Data() { std::cout << "構造函數\n"; }Data(const Data&) { std::cout << "拷貝構造\n"; }Data(Data&&) { std::cout << "移動構造\n"; }
};int main() {Data d;Data d2 = static_cast<Data&&>(d);  // 強制轉換為右值引用,觸發移動構造return 0;
}

? std::move 類似,但 static_cast<Data&&> 是顯式的轉換方式


4. 類型層次結構中的指針和引用轉換

類的繼承關系中,static_cast 可以在基類和派生類之間進行轉換,但僅限安全的向上轉換

#include <iostream>class Base {
public:virtual void show() { std::cout << "Base 類\n"; }
};class Derived : public Base {
public:void show() override { std::cout << "Derived 類\n"; }
};int main() {Derived d;Base* pBase = static_cast<Base*>(&d);  // 向上轉換pBase->show();  // 仍然調用 Derived 的 `show()`return 0;
}

?? 向下轉換(Base*Derived*)是不安全的,需要用 dynamic_cast


5. int 類型轉換為枚舉

static_cast 允許整數和枚舉類型之間的轉換

#include <iostream>enum Color { RED, GREEN, BLUE };int main() {int num = 1;Color c = static_cast<Color>(num);  // 將 int 轉換為枚舉類型std::cout << "c = " << c << std::endl;return 0;
}

? 適用于整數到枚舉的安全轉換


6. static_cast 在模板中的應用

在模板編程中,可以使用 static_cast 確保目標類型和原始類型一致

#include <iostream>
#include <type_traits>template <typename T, typename U>
T convert(U value) {static_assert(std::is_convertible<U, T>::value, "類型不兼容!");return static_cast<T>(value);
}int main() {double d = 3.14;int i = convert<int>(d);  // double → intstd::cout << "i = " << i << std::endl;return 0;
}

? static_assert 可用于編譯期檢查類型是否可以轉換


const_cast(去常性轉換)

特點描述
只能對同類型使用const_cast 類型必須相同。
不能用于基本數據類型不能用于基本數據類型之間的轉換(例如:int → double)。
轉換目標為指針或引用只能將指針或引用的常量屬性去除,而不能作用于值類型。

常量指針/引用被轉換為非常量的指針/引用,并仍然指向原來的對象

例子:

  1. 常量指針轉為非常量指針

    #include <iostream>void modifyValue(const int* ptr) {// const_cast 去常性轉換int* modifiablePtr = const_cast<int*>(ptr);*modifiablePtr = 20;  // 可以修改原對象
    }int main() {const int a = 10;modifyValue(&a);  // 將常量指針轉換為非常量指針return 0;
    }
    
  2. 常量引用轉為非常量引用

    #include <iostream>void modifyValue(const int& ref) {// const_cast 去常性轉換int& modifiableRef = const_cast<int&>(ref);modifiableRef = 20;  // 可以修改原對象
    }int main() {const int a = 10;modifyValue(a);  // 將常量引用轉換為非常量引用return 0;
    }
    

注意事項:

  • const_cast 只會移除常量屬性,并不會改變對象本身。
  • 對于常量對象的修改仍然是未定義行為,因此不應使用 const_cast 去修改那些原本是常量的數據。

reinterpret_cast(重新解釋轉換)

是 C++ 中最危險的類型轉換之一,它將數據從一種類型“強制”轉換為另一種類型,并且不進行任何類型檢查。
它是按解釋的

特點描述
最危險的轉換reinterpret_cast 不進行任何類型檢查,可能導致未定義行為。
按位解釋轉換直接基于內存的二進制表示,不考慮類型的語義。
指針之間的轉換可用于不同類型的指針之間的轉換。
指針與整數之間的轉換可將指針轉換為整數,反之亦然。

1. 指針類型轉換

#include <iostream>int main() {int a = 42;// 強制將 int* 轉換為 double*,危險操作,按位解釋double* p = reinterpret_cast<double*>(&a);std::cout << *p << std::endl;  // 不確定行為,可能崩潰return 0;
}

2. 指針與整數轉換

#include <iostream>int main() {int* p = reinterpret_cast<int*>(0x1234);  // 將整數轉換為指針std::cout << "Pointer: " << p << std::endl;uintptr_t addr = reinterpret_cast<uintptr_t>(p);  // 將指針轉換為整數std::cout << "Address as integer: " << addr << std::endl;return 0;
}

動態轉換(dynamic_cast

是一種用于在類層次結構中進行指針或引用類型轉換的操作,特別適用于下行轉換(基類指針或引用轉換為派生類指針或引用)。dynamic_cast運行時檢查類型安全,依賴于虛函數表和運行時類型信息(RTTI),通過虛函數表中的信息來實現類型檢查。

動態轉換的基本概念

  1. 上行轉換(向上轉換)

    • 向上轉換是指派生類對象轉換為基類指針或引用是在編譯時進行的,與靜態類型轉換等價,不查虛表
  2. 下行轉換(向下轉換)

    • 向下轉換是指基類指針或引用轉換為派生類指針或引用。這種轉換在運行時需要類型檢查
    • 并且只有在公有繼承和繼承關系中存在虛函數時才有效,否則沒有運行時類型信息(RTTI)進行類型檢查。
    • 使用 dynamic_cast 來進行下行轉換時,轉換成功時返回派生類指針或引用,轉換失敗時返回 nullptr(對于指針類型),或者拋出 std::bad_cast 異常(對于引用類型)。
    • 例如
      class Base {
      public:virtual ~Base() {}  // 必須有虛析構函數,以支持RTTI
      };class Derived : public Base {};int main() {Base* pBase = new Derived();Derived* pDerived = dynamic_cast<Derived*>(pBase);  // 成功,轉換為派生類指針if (pDerived) {std::cout << "轉換成功!" << std::endl;} else {std::cout << "轉換失敗!" << std::endl;}delete pBase;return 0;
      }
      
      • 如果 pBase 實際上指向一個 Derived 類型對象,則 pDerived 會成功轉換,并指向該對象。
      • 如果 pBase 并不指向 Derived 類型對象,dynamic_cast 將返回 nullptr,指示轉換失敗。

如何判斷是否能夠進行下行轉換

  • 條件:只有當類之間存在虛函數(如虛析構函數)時,RTTI 才會被啟用,dynamic_cast 才能進行類型檢查。
  • 執行流程
    1. dynamic_cast 會查詢對象的虛函數表(vtable)。
    2. 如果查詢到類型匹配,則轉換成功。
    3. 如果查詢失敗,則返回 nullptr(對于指針類型),或拋出異常 std::bad_cast(對于引用類型)。

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

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

相關文章

Cisco ASR1002查看資源占用的幾條命令

查看平臺資源 show platform resource 該命令用于顯示整個平臺的資源使用情況&#xff0c;包括 CPU、內存等 example: ASR1002# show platform resources **State Acronym: H - Healthy, W - Warning, C - Critical Resource…

Day 1:認知革命與DeepSeek生態定位

目標&#xff1a;建立對大模型技術范式的系統性認知&#xff0c;掌握DeepSeek的核心技術特性與生態價值 一、大模型技術演進&#xff1a;從GPT到DeepSeek 1.1 技術發展里程碑 2017-Transformer突破&#xff1a;Self-Attention機制如何突破RNN的序列建模瓶頸 2018-GPT初代&…

Python自動化辦公之Excel拆分

在日常辦公中&#xff0c;我們經常需要將包含多個Sheet頁的Excel文件拆分成多個獨立的Excel文件。例如&#xff0c;在發送Excel表給各部門確認時&#xff0c;出于控制知悉范圍最小等保密性考慮&#xff0c;每個部門只需要查看和確認自己部門對應的Sheet頁。手動拆分Excel文件非…

【CXX-Qt】1.1 Rust中的QObjects

本文涉及到了使用CXX-Qt將Rust、C和QML集成到Qt應用程序中的各個方面。下面&#xff0c;我將提供一個簡單的示例&#xff0c;演示如何使用CXX-Qt來創建一個Rust結構體并將其作為QObject子類暴露給C和QML。 一、設置CXX-Qt環境 首先&#xff0c;確保您已經安裝了Rust、CXX和CX…

Conda命令整理

Conda 是一個功能強大的包和環境管理工具&#xff0c;廣泛用于 Python 開發中。除了基本的包和環境管理功能外&#xff0c;Conda 還提供了許多高級用法和技巧&#xff0c;幫助用戶更高效地管理和維護 Python 環境。 1. 管理 Conda 本身 命令描述示例conda --version查看 Cond…

C++模擬實現AVL樹

目錄 1.文章概括 2.AVL樹概念 3.AVL樹的性質 4.AVL樹的插入 5.旋轉控制 1.左單旋 2. 右單旋 3.左右雙旋 4.右左雙旋 6.全部代碼 1.文章概括 本文適合理解平衡二叉樹的讀者閱讀&#xff0c;因為AVL樹是平衡二叉樹的一種優化&#xff0c;其大部分實現邏輯與平衡二叉樹是…

opc da 服務器數據 轉 EtherCAT項目案例

目錄 1 案例說明 2 VFBOX網關工作原理 3 應用條件 4 查看OPC DA服務器的相關參數 5 配置網關采集opc da數據 6 啟動EtherCAT從站轉發采集的數據 7 在服務器上運行仰科OPC DA采集軟件 8 案例總結 1 案例說明 在OPC DA服務器上運行OPC DA client軟件查看OPC DA服務器的相…

實驗9 基于WebGoat平臺的SQL注入攻擊

實驗9 基于WebGoat平臺的SQL注入攻擊 1.實驗目的 熟悉WebGoat平臺&#xff0c;在該平臺上實現SQL注入攻擊。 2.實驗內容 &#xff08;1&#xff09;下載webgoat-server-8.2.2.jar。 &#xff08;2&#xff09;搭建java環境。 &#xff08;3&#xff09;運行webgoat。 &#xf…

StochSync:可在任意空間中生成360°全景圖和3D網格紋理

StochSync方法可以用于在任意空間中生成圖像&#xff0c;尤其是360全景圖和3D網格紋理。該方法利用了預訓練的圖像擴散模型&#xff0c;以實現零-shot生成&#xff0c;消除了對新數據收集和單獨訓練生成模型的需求。StochSync 結合了 Diffusion Synchronization&#xff08;DS&…

研發管理知識

定義 研發管理是對研發活動進行有效的計劃、組織、領導和控制的過程&#xff0c;旨在通過合理配置資源、協調團隊工作、監控項目進度和質量等&#xff0c;確保研發項目能夠按時、按質、按量完成&#xff0c;實現企業的技術創新和產品升級目標&#xff0c;增強企業的核心競爭力。…

HarmonyOS 5.0應用開發——全局自定義彈出框openCustomDialog

【高心星出品】 文章目錄 全局自定義彈出框openCustomDialog案例開發步驟完整代碼 全局自定義彈出框openCustomDialog CustomDialog是自定義彈出框&#xff0c;可用于廣告、中獎、警告、軟件更新等與用戶交互響應操作。開發者可以通過CustomDialogController類顯示自定義彈出框…

AOS安裝及操作演示

文章目錄 一、安裝node1.1 在 macOS 上管理 Node版本1.1.1 安裝 nvm1.1.2 驗證 nvm 是否安裝成功1.1.3 使用 nvm 安裝/切換 Node.js 版本1.1.4 卸載 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安裝 nvm-windows1.2.2 安裝 Node.js 版本1.2.3 切換 Node.js 版本1.2.4 卸…

DeepSeek模型R1服務器繁忙,怎么解決?

在當今科技飛速發展的時代&#xff0c;人工智能領域不斷涌現出令人矚目的創新成果&#xff0c;其中DeepSeek模型無疑成為了眾多關注焦點。它憑借著先進的技術和卓越的性能&#xff0c;在行業內掀起了一股熱潮&#xff0c;吸引了無數目光。然而&#xff0c;如同許多前沿技術在發…

AIGC-微頭條爆款文案創作智能體完整指令(DeepSeek,豆包,千問,Kimi,GPT)

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總游戲腳本-輔助自動化Android控件全解手冊再戰Android系列Scratch編程案例軟考全系列Unity3D學習專欄藍橋系列AIGC(GPT、DeepSeek、豆包、千問、Kimi)??關于作者 專注于Android/Unity和各種游戲開發技巧,以及各種資…

[LLM面試題] 指示微調(Prompt-tuning)與 Prefix-tuning區別

一、提示調整(Prompt Tuning) Prompt Tuning是一種通過改變輸入提示語&#xff08;input prompt&#xff09;以獲得更優模型效果的技術。舉個例子&#xff0c;如果我們想將一條英語句子翻譯成德語&#xff0c;可以采用多種不同的方式向模型提問&#xff0c;如下圖所示&#xf…

CSS 性能優化全攻略:提升網站加載速度與流暢度

系列文章目錄 01-從零開始學CSS選擇器&#xff1a;屬性選擇器與偽類選擇器完全指南 02-避免樣式沖突&#xff1a;掌握CSS選擇器優先級與層疊規則的終極指南 03-如何精確掌控網頁布局&#xff1f;深入解析 CSS 樣式與盒模型 04-CSS 布局全面解析&#xff1a;從傳統浮動到現代 F…

自主項目面試點總結

1、許苑–OJ判題系統 技術棧&#xff1a;Spring BootSpring Cloud AlibabaRedisMybatisMQDocker 項目地址: https://github.com/xuyuan-upward/xyoj-backend-microservice 1.1、項目介紹: 一個基于微服務的OJ系統&#xff0c;具備能夠根據管理員預設的題目用例對用戶提交的代…

12.推薦系統的前沿技術

接下來我們將學習推薦系統的前沿技術。推薦系統是一個快速發展的領域&#xff0c;許多新技術和新方法不斷涌現&#xff0c;進一步提升了推薦系統的性能和效果。在這一課中&#xff0c;我們將介紹以下內容&#xff1a; 圖神經網絡&#xff08;GNN&#xff09;在推薦系統中的應用…

【py】python安裝教程(Windows系統,python3.13.2版本為例)

1.下載地址 官網&#xff1a;https://www.python.org/ 官網下載地址&#xff1a;https://www.python.org/downloads/ 2.64版本或者32位選擇 【Stable Releases】&#xff1a;穩定發布版本&#xff0c;指的是已經測試過的版本&#xff0c;相對穩定。 【Pre-releases】&#…

CEF132 編譯指南 MacOS 篇 - depot_tools 安裝與配置 (四)

1. 引言 在 CEF132&#xff08;Chromium Embedded Framework&#xff09;的編譯過程中&#xff0c;depot_tools 扮演著舉足輕重的角色。這套由 Chromium 項目精心打造的腳本和工具集&#xff0c;專門用于獲取、管理和更新 Chromium 及其相關項目&#xff08;包括 CEF&#xff…