cpp基礎學習筆記03:類型轉換

static_cast 靜態轉換

  • 用于類層次結構中基類和派生類之間指針或者引用的轉換。up-casting (把派生類的指針或引用轉換成基類的指針或者引用表示)是安全的;down-casting(把基類指針或引用轉換成子類的指針或者引用)是不安全的。
  • 用于基本數據類型之間的轉換,如把int轉換成char,這種轉換的安全性也要由開發人員來保證。
  • 可以把空指針轉換成目標類型的空指針(null pointer)。
  • 把任何類型的表達式轉換成void類型。
  • 注意: static_cast不能轉換掉expression的const、volitale或者__unaligned屬性。

基本類型轉換:

#include <iostream>int main()
{int b = 20;float ft = 30.25f;b = static_cast<float>(ft);std::cout << "After static_cast b: " << b << std::endl;std::cout << "Finished! \n";return 0;
}

類的基本轉換:

#include <iostream>class Base
{
public:Base(int data):_data(data){}void printData(){std::cout << "Base data: " << _data << std::endl;}private:int _data;
};class TestA : public Base
{
public:TestA(int num, int data): _num(num), Base(data){}void printData(){std::cout << "TestA Num: " << _num << std::endl;}private:int _num;
};int main()
{Base base{ 10 };TestA testA{ 10,20 };// 向上轉換Base* base_ptr = static_cast<Base*>(&testA);base_ptr->printData();// 向下轉換:危險行為TestA* test_ptr = static_cast<TestA*>(&base);test_ptr->printData();std::cout << "Finished! \n";return 0;
}

觀察,向上轉換正常,向下轉換數據未定義。

dynamic_cast

typeid必須是類的指針、類的引用或者void*。如果typeid是類的指針類型,那么expression也必須是指針,如果typeid是一個引用,那么expression也必須是一個引用。一般情況下,dynamic_cast用于具有多態性的類(即有虛函數的類)的類型轉換。

dynamic_cast依賴于RTTI信息,其次,在轉換時,dynamic_cast會檢查轉換的source對象是否真的可以轉換成target類型,這種檢查不是語法上的,而是真實情況的檢查。先看RTTI相關部分,通常,許多編譯器都是通過vtable找到對象的RTTI信息的,這也就意味著,如果基類沒有虛方法,也就無法判斷一個基類指針變量所指對象的真實類型,這時候,dynamic_cast只能用來做安全的轉換,例如從派生類指針轉換成基類指針。而這種轉換其實并不需要dynamic_cast參與。也就是說,dynamic_cast是根據RTTI記載的信息來判斷類型轉換是否合法的。

  • 主要用于類層次之間的up-casting和down-casting,還可以用于類之間的交叉轉換。在進行down-casting時,dynamic_cast具有類型檢查的功能,比static_cast更安全。檢測在運行時進行。如果被轉換的指針不是一個被請求的有效完整的對象指針,返回值為NULL。當用于多態類型時,它允許任意的隱式類型轉換以及相反過程。不過,與static_cast不同,在后一種情況里(注:即隱式轉 換的相反過程),dynamic_cast會檢查操作是否有效。也就是說,它會檢查轉換是否會返回一個被請求的有效的完整對象。

  • 注意:dynamic_cast不能轉換掉expression的const、volitale或者__unaligned屬性。

測試,加入現在的基類沒有定義虛函數:

class Base
{
public:Base(int data):_data(data){}void printData(){std::cout << "Base data: " << _data << std::endl;}private:int _data;
};class TestA : public Base
{
public:TestA(int num, int data): _num(num), Base(data){}void printData(){std::cout << "TestA Num: " << _num << std::endl;}private:int _num;
};int main()
{Base* base_ptr = new Base(10);TestA* test_ptr = new TestA(10,20);Base* ptr_01 = dynamic_cast<Base*>(test_ptr);ptr_01->printData();    // ok#if 0TestA* ptr_02 = dynamic_cast<TestA*>(base_ptr); // errorptr_02->printData();
#endifstd::cout << "Finished! \n";return 0;
}

重新定義并測試:

class VirtualBase
{
private:int _data;public:VirtualBase(int data): _data(data){}virtual ~VirtualBase(){}virtual void printData(){std::cout << "Virtual Base. Data: " << _data << std::endl;}
};class TestB : public VirtualBase
{
private:int _num;public:TestB(int num, int data): _num(num), VirtualBase(data){}~TestB(){}void printData() override{std::cout << "TestB. Data: " << _num << std::endl;}
};int main()
{// 定義VirtualBase* virual_base_ptr = new VirtualBase(30);TestB* test_b_ptr = new TestB(40, 50);// 派生類指向父類,okVirtualBase* ptr_03 = dynamic_cast<VirtualBase*>(test_b_ptr);ptr_03->printData();        // ok// 父類指向指向派生類,errorTestB* ptr_04 = dynamic_cast<TestB*>(virual_base_ptr);// ptr_04->printData();    // error// 轉換失敗返回了nullptr,所以一般需要額外判斷if (ptr_04 != nullptr)ptr_04->printData();std::cout << "Finished! \n";return 0;
}

reinterpret_cast

轉換一個指針為其他類型的指針,也允許將一個指針轉換為整數類型,反之亦然。這個操作符能夠在非相關的類型之間進行轉換。操作結果只是簡單的從一個指針到別的指針的值的二進制拷貝,在類型之間指向的內容不做任何類型的檢查和轉換。這是一個強制轉換。使用時有很大的風險,慎用之。(反正少用就完事兒了)

const_cast

這個類型操縱傳遞對象的const屬性,或者是設置或者是移除(也不常用)

參考資料

C++ | 四種類型轉換_c++四種類型轉換-CSDN博客

https://www.cnblogs.com/daihanlong/p/5550530.html

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

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

相關文章

【C# 】進度條控件 ProgressBar 使用

進度條控件ProgressBar控件&#xff0c;一般作為UI界面表示某個事情進行到某個程度的外觀的體現。 那么進度條控件ProgressBar控件&#xff0c;在form中是怎么使用的呢&#xff1f; 該控件必須要用的屬性如下&#xff1a; private System.Windows.Forms.ProgressBar progressB…

Flutter Version Manager (FVM): Flutter的版本管理終極指南

Flutter筆記 Flutter Version Manager (FVM) - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/article/details/136300307 my-websit…

SQL-Labs靶場“26-28”關通關教程

君衍. 一、二十六關 基于GET過濾空格以及注釋報錯注入1、源碼分析2、繞過思路3、updatexml報錯注入 二、二十六a關 基于GET過濾空格注釋字符型注入1、源碼分析2、繞過思路3、時間盲注 三、二十七關 基于union及select的過濾單引號注入1、源碼分析2、繞過思路3、聯合查詢注入4、…

laravel cache

一、基本操作 Cache::put() 創建緩存&#xff08;鍵&#xff0c;值&#xff0c;有效期&#xff08;單位是秒&#xff09;&#xff09; Cache::get() 獲取緩存 Cache::add() 只會在緩存項不存在的情況下添加數據到緩存&#xff0c;如果數據被成功返回 true&#xff0c;否則&…

Android在后臺讀取UVC攝像頭的幀數據流并推送

Android在后臺讀取UVC攝像頭的幀數據流并推送 添加UvcCamera依賴庫 使用原版的 saki4510t/UVCCamera 在預覽過程中斷開可能會閃退&#xff0c;這里使用的是 jiangdongguo/AndroidUSBCamera 中修改的版本&#xff0c;下載到本地即可。 https://github.com/jiangdongguo/AndroidU…

Rust學習筆記:基礎工具和基本名詞

不要用共享內存來通信&#xff0c;要用通信來共享內存 rustup: 一個用于管理 Rust 版本和相關工具的命令行工具 rustup update cargo: Rust 的構建系統和包管理工具 構建代碼下載依賴庫并構建下載庫 crate: 代碼包/庫 trait: 特性、功能 ///: 生成 html 格式的 doc&#…

CELL文獻速遞 | 了解微生物如何在社會中傳播并塑造我們的健康

谷禾健康 當人還是嬰兒時&#xff0c;會從父母那里得到微生物&#xff1b;和寵物玩耍或接觸時&#xff0c;也會從寵物那得到微生物&#xff1b;有時候人沒有直接和動物玩耍&#xff0c;只是接觸動物的糞便&#xff0c;甚至其他環境的微生物&#xff0c;都會交換微生物... 這些其…

智慧治水丨計訊物聯水利RTU助推小型水庫出險加固工程建設與管理

日前&#xff0c;水利部印發《關于健全小型水庫除險加固和運行管護機制的意見》&#xff08;以下簡稱《意見》&#xff09;&#xff0c;健全小型水庫除險加固和運行管護常態化機制&#xff0c;提高小型水庫安全管理水平。《意見》提出了“十四五”的兩大管理機制&#xff0c;通…

adb下載安裝及使用教程

adb下載安裝及使用教程 一、ADB的介紹1.ADB是什么&#xff1f;2.內容簡介3.ADB常用命令1. ADB查看設備2. ADB安裝軟件3. ADB卸載軟件4. ADB登錄設備shell5. ADB從電腦上發送文件到設備6. ADB從設備上下載文件到電腦7. ADB顯示幫助信息 4.為什么要用ADB 二、ADB的下載1.Windows版…

Flutter GetX 之 暗黑模式

我們緊接上篇文章,今天繼續講解一下強大的 GetX 的另一個功能,就是 暗黑模式 ,在iOS 13開始蘋果的應用慢慢的都開始適配 暗黑模式,andr。oid 也慢慢的 開始跟進,截止到目前,商店的大部分應用都已經完成了 暗黑模式 的適配。 原生開發為我們提供對應的 API,那么Flutter呢…

機器學習相關概念及術語總結

目錄 1.機器學習2.監督學習3.無監督學習4.線性回歸5.邏輯回歸 1.機器學習 機器學習的定義&#xff1a;一個計算機程序可從經驗E&#xff08;Experience&#xff09;中學習如何完成任務T&#xff08;Task&#xff09;&#xff0c;并且隨著經驗E的增加&#xff0c;性能指標P&…

Python中reduce函數和lambda表達式的學習

reduce函數將一個數據集合&#xff08;鏈表&#xff0c;元組等&#xff09;中的所有數據進行下列操作&#xff1a;用傳給 reduce 中的函數 function&#xff08;有兩個參數&#xff09;先對集合中的第 1、2 個元素進行操作&#xff0c;得到的結果再與第三個數據用 function 函數…

【論文精讀】DINOv2

摘要 學習與特定任務無關的預訓練表示已經成為自然語言處理的標準&#xff0c;這些表示不進行微調&#xff0c;即可在下游任務上明顯優于特定任務模型的性能。其主要得益于使用無監督語言建模目標對大量原始文本進行預訓練。 遵循NLP中的這種范式轉變&#xff0c;以探索計算機視…

iSlide插件2024免費版(包含52 個PPT設計輔助功能,9 大在線資源庫,以及超 50 萬 專業)

一、功能介紹 iSlide是一款專為PowerPoint設計的插件&#xff0c;它集合了眾多設計與效率提升的功能&#xff0c;幫助用戶更快速、更美觀地制作演示文稿。 主題設計&#xff1a;提供多種設計主題&#xff0c;用戶只需一鍵應用&#xff0c;即可為幻燈片賦予統一的視覺風格。智…

每次提出一個bug都讓測試重現,描述得那么清楚,自己操作下不會嗎?

一說到測試和開發的關系&#xff0c;你一定會想到一個詞“冤家”。 開發的工作就是按照PM的設計將產品最終造出來&#xff0c;而測試則是在開發已完成的工作里糾錯。so&#xff0c;測試的工作會讓開發很不爽&#xff0c;人之常情&#xff0c;誰都不喜歡自己的勞動成果被別人挑…

react路由基礎

1.目錄 A. 能夠說出React路由的作用 B. 能夠掌握react-router-dom的基本使用 C. 能夠使用編程式導航跳轉路由 D. 能夠知道React路由的匹配模式 2.目錄 A. React路由介紹 B. 路由的基本使用 C. 路由的執行過程 D. 編程式導航 E. 默認路由 F. 匹配模式 3.react路由介紹 現代…

開源項目:圖像分類技術在醫療影像分析中的應用與實踐

一、引言 在當今快速發展的醫療行業中&#xff0c;數字醫療正逐漸成為提升醫療服務質量和效率的關鍵力量。本項目旨在通過整合醫藥電商、遠程問診、慢病管理等多維度服務&#xff0c;為消費者和企業提供全面的醫療解決方案。項目的核心在于運用先進的圖像分類技術&#xff0c;以…

回歸測試:在不斷變化的環境中確保軟件的穩定性

軟件開發是一個復雜的過程&#xff0c;需要不斷變化和更新以滿足客戶不斷變化的需求&#xff0c;但它們也可能產生新問題或導致舊問題重新出現。這就是回歸測試的用武之地——它是在不斷變化的環境中確保軟件穩定性的重要組成部分。 在這篇文章中&#xff0c;我們將深入探討什…

第40期 | GPTSecurity周報

GPTSecurity是一個涵蓋了前沿學術研究和實踐經驗分享的社區&#xff0c;集成了生成預訓練Transformer&#xff08;GPT&#xff09;、人工智能生成內容&#xff08;AIGC&#xff09;以及大語言模型&#xff08;LLM&#xff09;等安全領域應用的知識。在這里&#xff0c;您可以找…

基于springboot + vue實現的前后端分離-在線旅游網站系統(項目 + 論文)

項目介紹 本旅游網站系統采用的數據庫是MYSQL &#xff0c;使用 JSP 技術開發&#xff0c;在設計過程中&#xff0c;充分保證了系統代碼的良好可讀性、實用性、易擴展性、通用性、便于后期維護、操作方便以及頁面簡潔等特點。 技術選型 后端: SpringBoot Mybatis 數據庫 : MyS…