C++多態的完成機制深刻懂得。本站提示廣大學習愛好者:(C++多態的完成機制深刻懂得)文章只能為提供參考,不一定能成為您想要的結果。以下是C++多態的完成機制深刻懂得正文
在面試進程中C++的多態完成機制常常會被面試官問道。年夜家清晰多態究竟該若何完成嗎?上面小編抽閒給年夜家引見下多態的完成機制。
1. 用virtual症結字聲名的函數叫做虛函數,虛函數確定是類的成員函數。
2. 存在虛函數的類都有一個一維的虛函數表叫做虛表。類的對象有一個指向虛表開端的虛指針。虛表是和類對應的,虛表指針是和對象對應的。
3. 多態性是一個接口多種完成,是面向對象的焦點。分為類的多態性和函數的多態性。
4. 多態用虛函數來完成,聯合靜態綁定。
5. 純虛函數是虛函數再加上= 0。
6. 籠統類是指包含至多一個純虛函數的類。
多態的簡略引見
普通來講,多態分為兩種,靜態多態和靜態多態。靜態多態也稱編譯時多態,重要包含模板和重載。而靜態多態則是經由過程類的繼續和虛函數來完成,當基類和子類具有同名同參同前往的辦法,且該辦法聲明為虛辦法,當基類對象,指針,援用指向的是派生類的對象的時刻,基類對象,指針,援用在挪用基類的辦法,現實上挪用的是派生類辦法。這就是靜態多態。
靜態多態的完成
靜態多態靠編譯器來完成,簡略來講就是編譯器對本來的函數名停止潤飾,在c說話中,函數沒法重載,是由於,c編譯器在潤飾函數時,只是簡略的在函數名前加高低劃線"_" 。而c++編譯器分歧,它依據函數的類型,個數來對函數名停止潤飾,這就使得函數可以重載,同理,模板也是可以完成的,針對分歧類型的實參來發生對應的特化的函數,經由過程增長潤飾,使得分歧的類型參數的函數得以辨別。
以下段法式為例
#include <iostream> using namespace std; template <typename T1, typename T2> int fun(T1 t1, T2 t2){} int foofun(){} int foofun(int){} int foofun(int , float){} int foofun(int , float ,double){} int main(int argc, char *argv[]) { fun(1, 2); fun(1, 1.1); foofun(); foofun(1); foofun(1, 1.1); foofun(1, 1.1, 1.11); return 0; }
經由編譯以後:
只拔取main函數部門來看:
可以發明,挪用的函數名均產生了變更,都加了響應的潤飾,使得挪用的函數是紛歧樣的,靜態多態就是如斯。
靜態多態的完成
聲明一個類時,假如類中有虛辦法,則主動在類中增長一個虛函數指針,該指針指向的是一個虛函數表,虛函數表中存著每一個虛函數真正對應的函數地址。靜態多態采取一種延遲綁定技巧,通俗的函數挪用,在編譯時代就曾經肯定了挪用的函數的地址,所以不管如何挪用,老是誰人函數,然則具有虛函數的類,在挪用虛函數時,起首去查虛函數表,然後在肯定挪用的是哪個函數,所以,挪用的函數是在運轉時才會肯定的。
在聲明基類對象時,虛函數表中綁定的就是基類的辦法的地址。在聲明派生類對象時,虛函數表中綁定的就是派生類的辦法。在對象被創立以後(以指針為例),不管是基類指針照樣派生類指針指向這個對象,虛函數表是不會轉變的。
以下段法式為例:
#include <iostream> using namespace std; class Base { public: virtual void fun() { cout << "this is base fun" << endl; } }; class Derived : public Base { public: void fun() { cout << "this is Derived fun" << endl; } }; int main(int argc, char *argv[]) { Base b1; Derived d1; Base *pb = &d1; Derived *pd = (Derived *)&b1; b1.fun(); pd->fun(); d1.fun(); pb->fun(); return 0; }
運轉成果以下:
從成果可以看出,當一個對象被創立以後,在挪用虛函數的時刻,不管是派生類指針照樣基類指針指向這個對象,挪用虛函數的成果是一樣的。由於,虛函數表是不變。固然,有能夠在多繼續中會有多個虛函數表從而招致函數挪用時挪用分歧的虛函數表,這裡不做斟酌。
以上所述是小編給年夜家引見的C++多態的完成機制懂得,願望對年夜家有所贊助,假如年夜家有任何疑問請給我留言,小編會實時答復年夜家的。在此也異常感激年夜家對網站的支撐!