網站首頁 編程語言 正文
引言
C++11引入了四種類型轉換接口,它們分別是static_cast、const_cast、dynamic_cast、reinterpret_cast。
為什么要使用這四種轉換呢?
給出面向對象編程和面向對象設計的五個基本原則,SOLID原則。
- Single Responsibility Principle:單一職責原則
- Open Closed Principle:開閉原則
- Liskov Substitution Principle:里氏替換原則
- Law of Demeter:迪米特法則
- Interface Segregation Principle:接口隔離原則
- Dependence Inversion Principle:依賴倒置原則
這里不詳細敘述五個基本原則,我們使用的cast接口和里氏替換原則有關。
里氏替換原則: “派生類(子類)對象可以在程式中代替其基類(超類)對象。” 以上內容并非利斯科夫的原文,而是譯自羅伯特·馬丁(Robert Martin)對原文的解讀[1]。
1、static_cast
1.1 基本類型轉換
1.2 類的上行轉換(安全)
用于子類指針或引用轉換為父類指針或引用。
#include <iostream> using namespace std; class Base { public: Base() {}; virtual void Show() { cout << "This is Base class"; } }; class Derived :public Base { public: Derived() {}; void Show() { cout << "This is Derived class"; } }; int main() { Derived* der = new Derived; auto Derived = static_cast<Base*> (der); //向上轉換一直是安全的 Derived->Show(); system("pause"); }
輸出結果為
This is Derived class
存在虛函數重載,則父類的函數被隱藏不能使用。
由于使用dynamic_cast
和static_cast
方法會存在開銷,則一般使用下列方法進行向上轉換。
class Base { public: Base(){}; virtual void Show(){cout<<"This is Base class";} }; class Derived:public Base { public: Derived(){}; void Show(){cout<<"This is Derived class";} }; int main() { Base *base ; Derived *der = new Derived; //向上轉換總是安全 base = der; base->Show(); system("pause"); }
1.3 類的下行轉換(不安全)
將父類指針、引用轉換為子類指針、引用,但需要程序員自己檢查,因此這種轉換方式也不存在額外的開銷。
2、const_cast
2.1 改變常量屬性
- 常量指針轉化為非常量指針;
- 常量引用轉化為非常量引用;
- 常量對象轉化為非常量對象
3、dynamic_cast
該轉換是運行時轉換,其余都是編譯時轉換。主要用于安全的向下進行轉換。同時當指針是智能指針時,使用dynamic_cast向下轉換不能成功,需使用dynamic_point_cast
來進行轉換。
3.1 類的上行轉換(安全)
此處和static_cast是一樣的,不再過多敘述。
#include <iostream> using namespace std; class Base { public: Base() {}; virtual void Show() { cout << "This is Base calss"; } }; class Derived :public Base { public: Derived() {}; void Show() { cout << "This is Derived class"; } }; int main() { Derived* der = new Derived; auto Derived = dynamic_cast<Base*> (der); //向上轉換一直是安全的 Derived->Show(); system("pause"); }
3.2 類的下行轉換(安全)
因為有類型檢查所以是安全的,但類型檢查需要運行時類型信息,這個信息位于虛函數表中,所以必須要有虛函數
,否則會轉換失敗。
在dynamic_cast轉換中分為兩種情況。
1、當基類指針指向派生對象時能夠安全轉換。
2、基類指針指向基類時會做檢查,轉換失敗,返回結果0。
#include <iostream> using namespace std; class Base { public: Base() {}; virtual void Show() { cout << "This is Base class" << endl; } }; class Derived :public Base { public: Derived() {}; void Show() { cout << "This is Derived class" << endl; } }; int main() { //第一種情況 Base* base = new Derived; Derived* der = dynamic_cast<Derived*>(base); //基類指針指向派生類對象時能夠安全轉換 der->Show(); //第二種情況 Base *base1 = new Base; if (Derived* der1 = dynamic_cast<Derived*> (base1)) { der1->Show(); } else { cout << "error!"; } delete(base); delete(base1); system("pause"); }
This is Derived class
error!
引用則和指針不同,指針在C++11中存在空指針,而引用不存在空引用,會引發bad_cast
異常。
#include <iostream> using namespace std; class Base { public: Base() {}; virtual void Show() { cout << "This is Base class" << endl; } }; class Derived :public Base { public: Derived() {}; void Show() { cout << "This is Derived class" << endl; } }; int main() { //基類引用子類 Derived b; Base& base1 = b; Derived& der1 = dynamic_cast<Derived&>(base1); der1.Show(); //基類引用基類 Base a; Base& base2 = a; try { Derived& der2 = dynamic_cast<Derived&>(base2); } catch(bad_cast) { cout << "bad_cast error!!" << endl; } system("pause"); }
This is Derived class
bad_cast error!!
4、reinterpret_cast
4.1 非關聯類型的轉換
操作結果是一個指針到其他指針的二進制拷貝,沒有類型檢查。
總結
原文鏈接:https://blog.csdn.net/qq_42301196/article/details/128839038
相關推薦
- 2023-04-29 vscode搭建python?Django網站開發環境的示例_python
- 2022-05-10 電商后臺開發之商品規格組合算法
- 2022-11-26 詳解redis-cli?命令_Redis
- 2023-12-23 uni-app消息推送uni-push使用
- 2022-06-06 layui 日期格式不正確(date、datetime)區別
- 2022-04-12 iOS SDK中引入第三方頭文件報Undefined symbols for architectur
- 2022-07-12 Linux命令之美|linux使用tar誤解壓之后,如何刪除解壓后的文件
- 2022-08-16 Golang輕量級IoC容器安裝使用示例_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支