網站首頁 編程語言 正文
1.什么是虛函數
C++類中用virtual
修飾的函數叫做虛函數,構造函數沒有虛構造函數,存在虛析構函數,C++所有虛函數都是一個指針去存儲的,所以具有虛函數的類,內存會增加一個指針大小的內存
#include<iostream> #include<string> using namespace std; class MM { public: //虛函數指針是同一個,所以無論該類中有多少個虛函數, //占用的內存就只是一個指針的大小 virtual void print() { cout << "我是第一個虛函數" << endl; } virtual void printData() { cout << "我是第二個虛函數" << endl; } protected: }; class son:public MM { public: void print() { //該函數也是虛函數, //父類中同名函數是虛函數 //所以子類該函數也是虛函數 } protected: }; int main() { cout << sizeof(MM) << endl; cout << "...................." << endl; //虛函數表的理解,下面帶圖解 MM mm; long long** p = (long long**)&mm; using Func = void(*)(); Func f1 = (Func)p[0][0]; Func f2 = (Func)p[0][1]; f1(); f2(); return 0; }
2.純虛函數
純虛函數也是虛函數的一種,只是沒有函數體,下面請看怎么表示沒有函數體
純虛函數——>虛函數=0;
具有一個或者多個虛函數的類叫做抽象類
- 抽象類不能構建對象
- 但是可以構建函數指針
#include<iostream> using namespace std; class MM { public: virtual void print() = 0; }; int main() { //MM mm; //抽象類不能構建對象 MM* pmm = nullptr; return 0; }
3.c++多態
多態指的是因為指針的不同的賦值操作所導致的同一行為的不同結果。多態的這個概念東西不太重要,重要的是什么樣的情況調用什么樣的行為
- 正常指針和正常對象調用行為,就近原則
- 父類指針被子類對象初始化
- 函數有
virtual
看對象類型 - 函數沒有
virtual
看指針類型 -
final
關鍵字 禁止子類重寫父類方法 -
override
顯示說明當前函數是重寫函數
多態三個必要性條件:
- 父類中存在虛函數
- 存在不正常指針的引用(不正常賦值關系)
-
public
繼承
#include<iostream> using namespace std; class MM { public: void print() { cout << "父類" << endl; } virtual void printData() { cout << "MM" << endl; } }; class son :public MM { public: void print() { cout << "子類" << endl; } void printData() { cout << "son" << endl; } }; int main() { MM* pmm = new son; pmm->print(); pmm->printData(); return 0; }
4.純虛函數和ADT過程
ADT:abstract data type
抽象數據類型,主要是通過繼承抽象類中,子類必須要實現父類的抽象方法,子類才可以創建對象。
#include<iostream> #include<string> using namespace std; class data { public: string name; int age; }; class MM { public: virtual bool empty() = 0; virtual int size() = 0; }; class List:public MM { public: bool empty() { return 0; } int size() { return NULL; } }; int main() { MM* pmm = new List; pmm->empty(); pmm->size(); }
5.虛析構函數
virtual
修飾的析構函數就是虛析構函數,當存在子類對象初始化父類指針的時候,父類析構函數就要是虛析構函數,否則只會釋放父類,存在內存泄漏問題
#include<iostream> using namespace std; class MM { public: virtual ~MM() { cout << "父類" << endl; } }; class son:public MM { public: ~son() { cout << "子類" << endl; } }; int main() { MM* pmm = new son; delete pmm; return 0; }
6.dynamic_cast類型轉換
- 上行轉換 子類到父類 和
staic_cast
差不多 - 下行轉換 父類到子類
dynamic_cast
更為安全 - 交叉轉換 多繼承
#include<iostream> using namespace std; class MM { public: virtual void print() { cout << "MM" << endl; } }; class son:public MM { public: void print() { cout << "son" << endl; } }; class A { public: virtual void print(){} }; class B { public: virtual void print() {} }; class C:public A,public B { public: void print() { cout << "c" << endl; } }; int main() { MM* partent = new MM; son* Son = new son; //上行轉換----->沒有必要 MM* p = static_cast<MM*>(Son); MM* pp = dynamic_cast<MM*>(Son); MM* ppp = Son; //可以 //下行轉換 son* x = dynamic_cast<son*>(partent); //安全,父類沒有virtual會報錯---->多態 if(!x) { printf("error"); } //下行轉換不安全,不會申請成功 A* a = new A; B* b = dynamic_cast<B*>(a); b->print(); return 0; }
7.成員函數指針
#include<iostream> #include<functional> using namespace std; class MM { public: void print() { cout << "king" << endl; } static void printData() { cout << "MM" << endl; } }; int main() { void(*p)() = &MM::printData; p(); //必須通過對象調用 void(MM::*pp)() = &MM::print; MM mm; (mm.*pp)(); //函數適配器,讓函數調用形態可以適用于別的形態 auto f = bind(&MM::print, &mm); f(); return 0; }
原文鏈接:https://blog.csdn.net/qq_72157449/article/details/128699474
相關推薦
- 2022-06-12 Python多線程的使用詳情_python
- 2022-10-17 docker網絡及部署集群和打包鏡像問題_docker
- 2022-04-14 如何解決:git push error: failed to push some refs to
- 2022-11-14 C#中的委托、事件與接口
- 2022-04-07 C++?string與int的相互轉換(使用C++11)_C 語言
- 2023-03-19 Android全面屏適配與判斷超詳細講解_Android
- 2022-04-14 Django執行指定腳本的幾種方法_python
- 2022-04-03 sqoop如何指定pg庫的模式(方法詳解)_相關技巧
- 最近更新
-
- 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同步修改后的遠程分支