1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      C++多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系

      這篇文章主要講解了“C++ 多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++ 多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系”吧!

      成都創(chuàng)新互聯(lián)是一家專業(yè)提供北辰企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)H5頁面制作、小程序制作等業(yè)務(wù)。10年已為北辰眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。

      多態(tài)與虛函數(shù)

      面向?qū)ο缶幊讨校鄳B(tài)的含義是“一個(gè)接口,多種實(shí)現(xiàn)”。
      多態(tài)分為靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)。靜態(tài)多態(tài)是通過模板化和重載技術(shù)來實(shí)現(xiàn),在編譯的時(shí)候確定。動(dòng)態(tài)多態(tài)通過虛函數(shù)和繼承關(guān)系來實(shí)現(xiàn),執(zhí)行動(dòng)態(tài)綁定,在運(yùn)行的時(shí)候確定。
      C++中運(yùn)行時(shí)的多態(tài)是指根據(jù)對象的實(shí)際類型來調(diào)用相應(yīng)的函數(shù)。如果對象類型是派生類,就調(diào)用派生類的函數(shù);如果對象類型是基類,就調(diào)用基類的函數(shù)。
      C++多態(tài)性是通過虛函數(shù)來實(shí)現(xiàn)的,虛函數(shù)允許子類重新定義成員函數(shù),而子類重新定義父類方法稱為覆蓋或重寫(override)。

      虛函數(shù):
      用virtual關(guān)鍵字申明的函數(shù)叫做虛函數(shù),虛函數(shù)肯定是類的成員函數(shù)。
      虛函數(shù)的作用就是實(shí)現(xiàn)動(dòng)態(tài)綁定,也就是在程序的運(yùn)行階段動(dòng)態(tài)地選擇合適的成員函數(shù)。
      具體的實(shí)現(xiàn)方式,在基類中定義了虛函數(shù)后,可以在基類的派生類中對虛函數(shù)重新定義,在派生類中重新定義的函數(shù)應(yīng)與虛函數(shù)具有相同的形參個(gè)數(shù)和形參類型,以實(shí)現(xiàn)統(tǒng)一的接口,不同定義過程。
      如果在派生類中沒有對虛函數(shù)重新定義,則它繼承其基類的虛函數(shù),此時(shí)派生類也為抽象類,不能實(shí)例化對象。

      虛函數(shù)表:
      當(dāng)一個(gè)類含有一個(gè)乃至多個(gè)虛函數(shù)的時(shí)候,將在全局?jǐn)?shù)據(jù)區(qū)(靜態(tài)區(qū))中存儲(chǔ)該類相應(yīng)的虛函數(shù)表vtbl,編譯器給類的每個(gè)對象添加一個(gè)相同隱藏的成員——虛函數(shù)表指針vptr,指向自身類的虛函數(shù)表。
      虛函數(shù)表的大小在編譯時(shí)確定,不必動(dòng)態(tài)分配內(nèi)存空間進(jìn)行存儲(chǔ),因此不虛函數(shù)表不存在堆中,根據(jù)以上特征,虛函數(shù)表類似于類中靜態(tài)成員變量。靜態(tài)成員變量也是全局共享,大小確定,所以虛函數(shù)表和靜態(tài)成員變量一樣,存放在全局?jǐn)?shù)據(jù)區(qū)。
      虛函數(shù)表中保存了類對象進(jìn)行聲明的虛函數(shù)的地址,即虛函數(shù)表的元素是指向類成員函數(shù)的指針。也就是說我們可以通過vptr訪問虛函數(shù)表,進(jìn)而訪問被聲明的虛函數(shù)的的地址,從而調(diào)用相應(yīng)的虛函數(shù)。
      同一個(gè)類的不同對象的vptr實(shí)際上指向同一張?zhí)摵瘮?shù)表。vptr的設(shè)定和重置都由每一個(gè)類的構(gòu)造函數(shù),析構(gòu)函數(shù)和拷貝賦值運(yùn)算符自動(dòng)完成。一般來說,將在構(gòu)造函數(shù)中進(jìn)行虛表的創(chuàng)建和虛表指針的初始化。
      基類的虛函數(shù)表和派生類的虛函數(shù)表分別為保存在不同位置的兩個(gè)獨(dú)立數(shù)組,也就是說基類的隱藏成員和派生類的隱藏成員指向不同的地址。
      如果派生類沒有重新定義基類的某個(gè)虛函數(shù)A,則派生類的虛函數(shù)表vtbl將保存基類的虛函數(shù)A的原始地址(此時(shí)派生類和基類的虛函數(shù)表中保存的虛函數(shù)A的地址是一樣的)。
      如果派生類重寫了基類的某個(gè)虛函數(shù)B,則派生類的虛函數(shù)表vtbl將保存新的虛函數(shù)B的地址(此時(shí)的虛函數(shù)B其實(shí)有兩個(gè)版本,分別被基類和派生類的虛函數(shù)表分開保存)。

      純虛函數(shù):
      純虛函數(shù)是在基類中聲明的虛函數(shù),它在基類中沒有定義,要求任何派生類都要定義自己的實(shí)現(xiàn)方法。在基類中實(shí)現(xiàn)純虛函數(shù)的方法是在函數(shù)原型后加“=0”,即virtual void funtion1() = 0;
      含有純虛函數(shù)的類為抽象類,不能聲明對象,只是作為基類為派生類服務(wù)。除非在派生類中完全實(shí)現(xiàn)基類的所有虛函數(shù),否則派生類也是抽象類,不能實(shí)例化對象。
      抽象類不能定義對象,但是可以作為指針或引用類型使用。

      不能聲明虛函數(shù):
      常見的不能聲明為虛函數(shù)的有:普通函數(shù)(非成員函數(shù));靜態(tài)成員函數(shù);內(nèi)聯(lián)成員函數(shù);構(gòu)造函數(shù);友元函數(shù)。
      普通函數(shù)(非成員函數(shù))只能被overload,不能被override,聲明為虛函數(shù)也沒有意義。
      靜態(tài)成員函數(shù)對于每個(gè)類來說只有一份代碼,所有的對象都共享這一份代碼,也沒有要?jiǎng)討B(tài)綁定的必要性。
      內(nèi)聯(lián)函數(shù)在編譯時(shí)被展開,從而可減少函數(shù)調(diào)用花費(fèi)的代價(jià),虛函數(shù)是在運(yùn)行時(shí)才進(jìn)行動(dòng)態(tài)綁定,從而使得繼承對象能夠準(zhǔn)確的執(zhí)行自己的動(dòng)作。
      構(gòu)造函數(shù)目的是為了生成對象時(shí)進(jìn)行對象初始化,虛函數(shù)目的是在不同類型的對象中調(diào)用不同的方法以產(chǎn)生不同的動(dòng)作,當(dāng)對象還沒有生成時(shí),虛函數(shù)是沒有意義的,而構(gòu)造函數(shù)是為了在對象還沒有生成時(shí)實(shí)例化對象。
      友元函數(shù)不支持繼承,對于沒有繼承特性的函數(shù)就沒有虛函數(shù)的說法。

      早綁定和晚綁定:
      c++編譯器在編譯的時(shí)候,要確定每個(gè)對象調(diào)用的函數(shù)(非虛函數(shù))的地址,這稱為早期綁定,當(dāng)我們將Son類對象的地址賦給指針pFather時(shí),C++編譯器進(jìn)行了類型轉(zhuǎn)換,此時(shí)C++編譯器認(rèn)為指針變量pFather保存的就是Father對象的地址,當(dāng)在main函數(shù)中執(zhí)行pFather->Say(),調(diào)用的是Father對象的Say函數(shù)。
      從內(nèi)存角度看:

      C++ 多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系

      前面輸出的結(jié)果是因?yàn)榫幾g器在編譯的時(shí)候,就已經(jīng)確定了對象調(diào)用的函數(shù)地址,要解決這個(gè)問題就要使用晚綁定,當(dāng)編譯器使用晚綁定時(shí)候,就會(huì)在運(yùn)行時(shí)再去確定對象的類型以及正確的調(diào)用函數(shù),而要讓編譯器采用晚綁定,就要在基類中聲明函數(shù)時(shí)使用virtual關(guān)鍵字.一旦某個(gè)函數(shù)在基類中聲明為virtual,那么在所有的派生類中該函數(shù)都是virtual,而不需要再顯式地聲明為virtual。

      編譯器為每個(gè)對象提供了一個(gè)虛表指針(即vptr),這個(gè)指針指向了對象所屬類的虛表,在程序運(yùn)行時(shí),根據(jù)對象的類型去初始化vptr,從而讓vptr正確的指向了所屬類的虛表,從而在調(diào)用虛函數(shù)的時(shí)候,能夠找到正確的函數(shù)。由于pFather實(shí)際指向的對象類型是Son,因此vptr指向的Son類的vtable,當(dāng)調(diào)用pFather->Son()時(shí),根據(jù)虛表中的函數(shù)地址找到的就是Son類的Say()函數(shù)。
      從內(nèi)存角度看:

      在這里插入圖片描述

      構(gòu)造函數(shù)與虛函數(shù)

      構(gòu)造函數(shù)不能為虛函數(shù)。
      從C++之父Bjarne的回答我們應(yīng)該知道C++為什么不支持構(gòu)造函數(shù)是虛函數(shù)了,簡單講就是沒有意義。
      虛函數(shù)的作用在于通過子類的指針或引用來調(diào)用父類的那個(gè)成員函數(shù)。而構(gòu)造函數(shù)是在創(chuàng)建對象時(shí)自己主動(dòng)調(diào)用的,不可能通過子類的指針或引用去調(diào)用。

      構(gòu)造函數(shù)目的是為了生成對象時(shí)進(jìn)行對象初始化,虛函數(shù)目的是在不同類型的對象中調(diào)用不同的方法以產(chǎn)生不同的動(dòng)作,當(dāng)對象還沒有生成時(shí),內(nèi)存中不存在虛函數(shù)指針和虛函數(shù)表,此時(shí)虛函數(shù)是沒有意義的,而構(gòu)造函數(shù)是為了在對象還沒有生成時(shí)實(shí)例化對象,如果構(gòu)造函數(shù)被聲明為虛函數(shù),內(nèi)存空間還沒有虛函數(shù)表,該構(gòu)造函數(shù)將變得沒有意義,所以構(gòu)造函數(shù)不能是虛函數(shù)。

      析構(gòu)函數(shù)與虛函數(shù)

      當(dāng)派生類指針指向用new運(yùn)算符生成的派生類對象時(shí),delete派生類指針,將執(zhí)行派生類的析構(gòu)函數(shù),再執(zhí)行基類的析構(gòu)函數(shù)。因?yàn)樵趯?shí)例化派生類對象時(shí),先實(shí)例了基類對象。
      當(dāng)基類指針指向用new運(yùn)算符生成的派生類對象時(shí),delete基類指針,因?yàn)榫幾g器又進(jìn)行了類型轉(zhuǎn)換,默認(rèn)為基類指針指向基類對象的地址,根據(jù)早綁定中內(nèi)存的關(guān)系,如果基類析構(gòu)函數(shù)沒有聲明為虛函數(shù),將只執(zhí)行基類的構(gòu)造函數(shù),如果基類析構(gòu)函數(shù)聲明為虛函數(shù),盡管進(jìn)行類型轉(zhuǎn)換,根據(jù)晚綁定中內(nèi)存的關(guān)系,不管基類對象還是派生類對象都有相應(yīng)的虛函數(shù)表指針,因此析構(gòu)時(shí)會(huì)先調(diào)用派生類的析構(gòu)函數(shù)(vptr指向自身的析構(gòu)函數(shù)),再調(diào)用基類的析構(gòu)函數(shù)(聲明派生類對象先實(shí)例了基類對象)。

      #include
      using namespace std;
      
      class Base {
      public:
          Base()
          { 
              cout<<"Base::Base()"<

      感謝各位的閱讀,以上就是“C++ 多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對C++ 多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!


      新聞名稱:C++多態(tài)與虛函數(shù)、與構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么聯(lián)系
      本文URL:http://www.ef60e0e.cn/article/giopoi.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        潼关县| 什邡市| 夹江县| 寿宁县| 永济市| 鸡西市| 桦川县| 新沂市| 偃师市| 环江| 清新县| 濮阳县| 扎鲁特旗| 射洪县| 厦门市| 麟游县| 锡林郭勒盟| 拉萨市| 渑池县| 浪卡子县| 新和县| 郁南县| 剑阁县| 岐山县| 漳平市| 普兰店市| 京山县| 竹溪县| 龙州县| 都江堰市| 吴川市| 曲麻莱县| 永寿县| 南溪县| 莎车县| 黑河市| 汪清县| 浙江省| 岳普湖县| 玉门市| 周宁县|