Cpp::靜態 動態的類型轉換全解析(36)

文章目錄

  • 前言
  • 一、C語言中的類型轉換
  • 二、為什么C++會有四種類型轉換?
    • 內置類型 -> 自定義類型
    • 自定義類型 -> 內置類型
    • 自定義類型 -> 自定義類型
    • 隱式類型轉換的坑
  • 三、C++強制類型轉換
    • static_cast
    • reinterpret_cast
    • const_cast
    • dynamic_cast
  • 四、RTTI
  • 總結


前言

??Hello,學完這個,再看看 IO 流,我們的C++學習之路可能真的要結束了~


一、C語言中的類型轉換

??在學習C++之前,不妨我們先看看C的類型轉換的機制:

??在C語言中,如果賦值運算符左右兩側類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發生類型轉化

??C語言中總共有兩種形式的類型轉換:隱式類型轉換(整型之間 整型浮點數之間) 和 顯式類型轉換(指針之間 整型指針之間)

沒有關聯的類型不支持轉換

  1. 隱式類型轉化:編譯器在編譯階段自動進行,能轉就轉,不能轉就編譯失敗。
  2. 顯式類型轉化:需要用戶自己處理。
#include<iostream>
using namespace std;int main()
{int i = 1;// 隱式類型轉換double d = i;printf("%d, %.2f\n", i, d);int* p = &i;// 顯示的強制類型轉換int address = (int)p;printf("%p, %d\n", p, address);// “類型強制轉換”: 無法從“int *”轉換為“double”// double x = (double)p;// 沒有關聯的類型不支持轉換return 0;
}

二、為什么C++會有四種類型轉換?

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

  1. 隱式類型轉化有些情況下可能會出問題:比如數據精度丟失
  2. 顯式類型轉換將所有情況混合在一起,代碼不夠清晰

??C++除了兼容C的轉換用法之外還有三種轉換方式:內置類型 -> 自定義類型 ;自定義類型 -> 內置類型 ; 自定義類型 -> 自定義類型

內置類型 -> 自定義類型

??內置類型轉換為自定義類型通過 隱式類型轉換 + 對應的構造函數 就能夠實現

class A
{
public:A(int a1):_a1(a1){}A(int a1, int a2):_a1(a1),_a2(a2){}
private:int _a1 = 1;int _a2 = 1;
};int main()
{// 內置類型 -> 自定義類型A aa1 = 1;// 單參數隱式類型轉換A aa2 = { 1,2 };// 多參數隱式類型轉換,使用{}// A aa3 = { 1,2,3 };// 沒有實現3個參數的構造函數或者initializer_list,就不能隱式類型轉換return 0;
}

在這里插入圖片描述

自定義類型 -> 內置類型

??自定義類型轉化為內置類型,直接寫不支持,需要寫重載函數

class A
{
public:A(int a1):_a1(a1){}// 自定義類 -> 內置類型 重載函數operator int(){return _a1 + _a2;}
private:int _a1 = 1;int _a2 = 1;
};int main()
{// 內置類型 -> 自定義類型A aa1 = 1;// 自定義類型 -> 內置類型 直接寫不支持,需要重載int x = aa1;cout << x << endl;return 0;
}

在這里插入圖片描述

自定義類型 -> 自定義類型

??自定義類型轉換為自定義類型,直接寫不支持,需要加拷貝構造

class A
{
public:A(int a1):_a1(a1){}// 成員變量私有,類外不能獲取,const對象需要加constint get() const{return _a1;}
private:int _a1 = 1;int _a2 = 1;
};class B
{
public:B(const A& aa):_b1(aa.get()){}
private:int _b1;
};int main()
{// 內置類型 -> 自定義類型A aa1 = 1;// 自定義類型 -> 自定義類型 直接寫不支持,需要加拷貝構造B bb = aa1;return 0;
}

在這里插入圖片描述

隱式類型轉換的坑

// 隱式類型轉換的坑
void Insert(size_t pos)
{int end = 10;while (end >= pos){cout << end << endl;--end;}
}int main()
{Insert(5);// 插入0就有坑,-1轉換為無符號整數為最大值Insert(0);return 0;
}

在這里插入圖片描述

三、C++強制類型轉換

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

static_cast、reinterpret_cast、const_cast、dynamic_cast

static_cast

??static_cast用于非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可用static_cast

一樣的,但它不能用于兩個不相關的類型進行轉換

int main()
{int i = 1;// 隱式類型轉換 : static_castdouble d = static_cast<double>(i);cout << d << endl;// 強制類型轉換int* p = &i;//int address = static_cast<int>(p);//printf("%p %d\n", p, address);return 0;
}

在這里插入圖片描述

class A
{
public:A(int a1):_a1(a1){}
private:int _a1 = 1;int _a2 = 1;
};int main()
{// 隱式類型轉換,使用staticA aa1 = 1;A aa2 = static_cast<int>(1);return 0;
}

在這里插入圖片描述

reinterpret_cast

??reinterpret_cast操作符通常為操作數的位模式提供較低層次的重新解釋,用于將一種類型轉換為另一種不同的類型(強制類型轉換)

int main()
{int i = 1;// 強制類型轉換 : reinterpret_castint* p = &i;int address = reinterpret_cast<int>(p);printf("%p %d\n", p, address);return 0;
}

在這里插入圖片描述

const_cast

??const_cast最常用的用途就是刪除變量的const屬性,方便賦值

int main()
{const int i = 1;// 存放到寄存器中int* ptr = (int*)&i;(*ptr)++;cout << *ptr << endl;cout << i << endl;return 0;
}

在這里插入圖片描述
??我們能夠看到一個很奇怪的現象,我們將 i 地址處的數據++,該地址處的值修改了,但是 i 的值卻沒有修改,這是為什么呢?

實際是在C++程序中,使用 const 修飾的變量是存放在寄存器中的,最終打印該值是直接打印寄存器存儲的值

dynamic_cast

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

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

  1. dynamic_cast只能用于父類含有虛函數的類 。
  2. dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回0。
class A
{
public:virtual void f(){}int _a1 = 1;
};class B : public A
{
public:int _b1 = 1;
};void func(A* pa)
{// 不差別轉換,存在風險// 傳A對象的地址,沒有_b1成員,修改_b1成員則程序崩潰B* pb = (B*)pa;cout << pb << endl;pb->_b1++;
}int main()
{A a;B b;func(&a);func(&b);return 0;
}

在這里插入圖片描述

class A
{
public:virtual void f(){}int _a1 = 1;
};class B : public A
{
public:int _b1 = 1;
};// 使用dynamic_cast,父類必須有虛函數
void func(A* pa)
{// pa指向a對象,轉換成功// pa指向b對象,轉換失敗,返回nullptrB* pb = dynamic_cast<B*>(pa);if (pb){cout << pb << endl;pb->_b1++;}else{cout << "轉換失敗" << endl;}
}int main()
{A a;B b;func(&a);func(&b);return 0;
}

在這里插入圖片描述

四、RTTI

RTTI:Run-time Type identi?cation的簡稱,即:運行時類型識別

C++通過以下方式來支持RTTI:

??1. typeid運算符
??2. dynamic_cast運算符
??3. decltype


總結

??蕪湖,馬上就要迎來最后一節了!

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

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

相關文章

2024年終總結:技術成長與突破之路

文章目錄 前言一、技術成長&#xff1a;菜鳥成長之路1. 學習與實踐的結合2. 技術分享與社區交流 二、生活與事業的平衡&#xff1a;技術之外的思考1. 時間管理與效率提升2. 技術對生活的積極影響 三、突破與展望&#xff1a;未來之路1. 技術領域的突破2. 未來規劃與目標 四、結…

ComfyUI實現老照片修復——AI修復老照片(ComfyUI-ReActor / ReSwapper)解決天坑問題及加速pip下載

AI修復老照片&#xff0c;試試吧&#xff0c;不一定好~~哈哈 2023年4月曾用過ComfyUI&#xff0c;當時就感慨這個工具和虛幻的藍圖很像&#xff0c;以后肯定是專業人玩的。 2024年我寫代碼去了&#xff0c;AI做圖沒太關注&#xff0c;沒想到&#xff0c;現在ComfyUI真的變成了工…

思科交換機telnet配置案例

目錄 1.telnet簡述2.網絡拓撲3.設備說明4.網絡配置4.1 電腦PC ip設置4.2 網絡交換機telnet配置 5.小結 1.telnet簡述 Telnet是遠程登錄服務的一個協議&#xff0c;該協議定義了遠程登錄用戶與服務器交互的方式。它允許用戶在一臺聯網的計算機上登錄到一個遠程分時系統中&#…

WPS數據分析000006

一、排序 開始→ 排序 同文件→選項→自定義序列→輸入序列 二、篩選 高級篩選 條件區域要與列表區域一樣。 三、條件格式

vofa++使用方法

控件區可以添加控件用來啊多樣顯示 點擊一個控件然后右鍵可以選擇要添加顯示的數據&#xff0c;點all表全部顯示&#xff0c; 點auto可以自動布局 要用控件需要選擇協議&#xff0c;不知道協議具體格式可以點擊問號看看&#xff0c;并且最好用printf重定義來實現 比如我要實現F…

達夢拷貝DM_HOME的復制安裝

近期一個項目需求&#xff0c;需要在沒有安裝包的情況下&#xff0c;將達夢數據庫安裝到虛機上&#xff08;生產機上安裝了達夢&#xff09;&#xff0c;故采用直接打包生產機DM_HOME的方式拷貝至虛機&#xff0c;再依次執行達夢的部分指令完成安裝。以下為驗證的步驟&#xff…

tomcat的accept-count、max-connections、max-threads三個參數的含義

tomcat的accept-count、max-connections、max-threads三個參數的含義 tomcat的accept-count、max-connections、max-threads三個參數的含義 max-connections&#xff1a;最大連接數 最大連接數是指&#xff0c;同一時刻&#xff0c;能夠連接的最大請求數 需要注意的是&#x…

ui文件轉py程序的工具

源博客連接&#xff1a; PyCharm中利用外部工具uic轉成的py文件&#xff0c;里面全是C代碼&#xff0c;并非python類型的代碼&#xff0c;導致大量報錯。。。_pyside6-uic為什么把ui轉為了c-CSDN博客 如果想把ui文件轉為py文件&#xff0c;首先設置pycharm的外部工具&#xf…

hedfs和hive數據遷移后校驗腳本

先談論校驗方法&#xff0c;本人騰訊云大數據工程師。 1、hdfs的校驗 這個通常就是distcp校驗&#xff0c;hdfs通過distcp遷移到另一個集群&#xff0c;怎么校驗你的對不對。 有人會說&#xff0c;默認會有校驗CRC校驗。我們關閉了&#xff0c;為什么關閉&#xff1f;全量遷…

61,【1】BUUCTF WEB BUU XSS COURSE 11

進入靶場 左邊是吐槽&#xff0c;右邊是登錄&#xff0c;先登錄試試 admin 123456 admiin# 123456 admin"# 123456 不玩了&#xff0c;先去回顧下xss 回顧完就很尷尬了&#xff0c;我居然用SQL的知識去做xss的題 重來 吐槽這里有一個輸入框&#xff0c;容易出現存儲型…

海外問卷調查如何影響企業的經營?在品牌建設中有何指導意義?

市場調查的定義&#xff1a;通過科學的方法&#xff0c;有目的地、系統地搜集整理一些市場信息&#xff0c;其目的在于了解當下市場現狀和發展前景&#xff0c;為企業生產和品牌打造提供一些科學的指導意見&#xff0c;這是任何大企業、中小企業、初創企業都必須重視的一個重要…

STM32新建不同工程的方式

新建工程的方式 1. 安裝開發工具 MDK5 / keil52. CMSIS 標準3. 新建工程3.1 寄存器版工程3.2 標準庫版工程3.3 HAL/LL庫版工程3.4 HAL庫、LL庫、標準庫和寄存器對比3.5 庫開發和寄存器的關系 4. STM32CubeMX工具的作用 1. 安裝開發工具 MDK5 / keil5 MDK5 由兩個部分組成&#…

idea maven本地有jar包,但還要從遠程下載

idea 中&#xff0c;java 工程執行 maven reimport&#xff0c;報jar報無法下載。 我奇了個怪&#xff0c;我明明在本地倉庫有啊&#xff0c;你非得從遠程下載&#xff1f; 我從供應商那里拿來的&#xff0c;遠程當然沒有了。 這太奇葩了吧&#xff0c;折騰好久不行。 后來…

springboot 調用 c++生成的so庫文件

一、創建c文件 SoTest.h #pragma once class SoTest {int Add(int a,int b); };SoTest.cpp #include "SoTest.h"int SoTest::Add(int a, int b) {return a b; }二、創建so文件 /home/ubuntu/projects/SoTest/bin/x64/Debug/libSoTest.so 三、java代碼 Maven依…

Windows 靶機常見服務、端口及枚舉工具與方法全解析:SMB、LDAP、NFS、RDP、WinRM、DNS

在滲透測試中&#xff0c;Windows 靶機通常會運行多種服務&#xff0c;每種服務都有其默認端口和常見的枚舉工具及方法。以下是 Windows 靶機常見的服務、端口、枚舉工具和方法的詳細說明&#xff1a; 1. SMB&#xff08;Server Message Block&#xff09; 端口 445/TCP&…

250125-package

1. 定義 包就是文件夾&#xff0c;作用是在大型項目中&#xff0c;避免不同人的編寫的java文件出現同名進而導致報錯&#xff1b;想象一個場景&#xff0c;在一個根目錄中&#xff0c;每一個人都有自己的一個java文件夾&#xff0c;他可以將自己編寫的文件放在該文件夾里&…

系統思考—動態問題分析

“不是解決問題&#xff0c;而是根本改變它的方式&#xff0c;才能真正創造持久的成功。”——彼得德魯克 在很多情況下&#xff0c;企業面對問題時&#xff0c;總會急于尋找解決方案&#xff0c;但這些方案往往只是暫時的“應急措施”。它們看似有效&#xff0c;卻難以從根本…

ASP.NET Core WebAPI的異步及返回值

目錄 Action方法的異步 Action方法參數 捕捉URL占位符 捕捉QueryString的值 JSON報文體 其他方式 Action方法的異步 Action方法既可以同步也可以異步。異步Action方法的名字一般不需要以Async結尾。Web API中Action方法的返回值如果是普通數據類型&#xff0c;那么返回值…

系統架構設計師教材:信息系統及信息安全

信息系統 信息系統的5個基本功能&#xff1a;輸入、存儲、處理、輸出和控制。信息系統的生命周期分為4個階段&#xff0c;即產生階段、開發階段、運行階段和消亡階段。 信息系統建設原則 1. 高層管理人員介入原則&#xff1a;只有高層管理人員才能知道企業究竟需要什么樣的信…

Golang Gin系列-5:數據模型和數據庫

在這篇Gin教程的博客中&#xff0c;我們將探索如何將模型和數據庫與Gin框架無縫集成&#xff0c;使你能夠構建健壯且可擴展的web應用程序。通過利用流行的庫并遵循最佳實踐&#xff0c;你將學習如何定義模型、建立數據庫連接、執行CRUD操作以及確保基于gin的項目中的數據完整性…