<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1.當在類中使用virtual宣告一個函數為虛擬函式時,在編譯時,編譯器會自動在基礎類別中默默地安插一個虛擬函式表指標,同時的.rodata段為這類生成一張虛擬函式表,用來儲存類中的虛擬函式的地址。
2.當繼承發生時,父類別中的虛指標就被子類給繼承了下來,所以他的類物件空間就增大了一個指標的大小。
3.當子類構造物件時,這根繼承而來的虛指標,將會在子類別建構函式中被重新賦值,所賦的值即為子類類中產生的虛擬函式表地址。
4.當使用父類別指標或參照,對虛擬函式進行呼叫時,通過這個虛擬函式表指標,在虛擬函式表中查詢虛擬函式的地址,從而呼叫不同類的虛擬函式。
虛擬函式的意義何在?就是用來承接動態多型的。他是如何承接這種動態多型機制的呢?
當子類之中函數與父類別之中的虛擬函式重名時,且返回值與形參列表都一致時,將是對父類別虛擬函式的重寫。當在子類重寫虛擬函式時,將會把虛擬函式表中的父類別的虛擬函式地址覆蓋掉。
1.有繼承關係
2.基礎類別中有虛擬函式,且子類重寫虛擬函式
3.基礎類別指標或參照,指向或參照父類別物件,就會形成動態多型
#include <iostream> using namespace std; class Driver{ public: virtual void show_info() { cout<<"我是司機"<<endl; } }; class Bwm:public Driver { public: void show_info() { cout<<"我開的是寶馬"<<endl; } }; class Benchi:public Driver { public: void show_info() { cout<<"我開的是賓士"<<endl; } }; class Tuolaji:public Driver { public: void show_info() { cout<<"我開的是拖拉機"<<endl; } }; class Kai { public: void kaiche(Driver& p) { p.show_info(); } }; int main() { Bwm bwm; Tuolaji tuolaji; Benchi benchi; Kai p; p.kaiche(tuolaji); p.kaiche(benchi); p.kaiche(benchi); return 0; }
結果圖:
#include <iostream> using namespace std; class A { public: A() { cout<<"A的構造"<<endl; } ~A() { cout<<"A的解構"<<endl; } virtual void show_info() { cout<<"愛吃飯"<<endl; } }; class B:public A { public: B() { cout<<"B的構造"<<endl; } ~B() { cout<<"B的解構"<<endl; } void show_info() { cout<<"愛吃糖"<<endl; } }; int main() { A* a=new B; a->show_info(); delete a; return 0; }
結果圖:
由圖可知:當用虛擬函式實現多型的時候,子類的的解構無法進行。
所以我們應該怎麼解決呢?
#include <iostream> using namespace std; class A { public: A() { cout<<"A的構造"<<endl; } virtual~A() { cout<<"A的解構"<<endl; } virtual void show_info() { cout<<"愛吃飯"<<endl; } }; class B:public A { public: B() { cout<<"B的構造"<<endl; } ~B() { cout<<"B的解構"<<endl; } void show_info() { cout<<"愛吃糖"<<endl; } }; int main() { A* a=new B; a->show_info(); delete a; return 0; }
結果圖:
所以,為了避免子類的解構無法執行而造成的記憶體漏失問題,應該把最遠端父類別的解構函式定義為虛解構。虛解構的語法即是在最遠端父類別的解構函式名前 加virtual進行修飾即可。
虛解構如下:
virtual~A() { //虛解構的定義形式。 }
class + 類名
{
public:
virtual void showInfo() = 0;
};
在類中定義一個沒有函數體的虛擬函式就叫做純虛擬函式。類中有純虛擬函式的類就叫做抽象類。抽象類被人稱介面類。這個純虛擬函式只有一個函數名做為函數功能的表現,而沒有函數體的實現。純虛擬函式必須在子類之中進行實現,如果繼承的子類沒有實現父類別的純虛擬函式,那麼這個子類也將成員抽象類。抽象類是不可以定義物件的。純虛擬函式也叫介面類中的介面。
#include <iostream> using namespace std; class A { public: virtual void show_info()=0; virtual void goshopping()=0; }; class B:public A { public: void show_info() { cout<<"我是大哥"<<endl; } void goshopping() { cout<<"我是小弟"<<endl; } }; int main() { A* a=new B; a->show_info(); a->goshopping(); return 0; }
到此這篇關於深入瞭解C++的多型與虛擬函式的文章就介紹到這了,更多相關C++多型 虛擬函式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45