-
純虛函數(shù):virtual int func() = 0;不需要去實現(xiàn)函數(shù)的時候用。 純虛函數(shù)在虛函數(shù)列表中存儲的值就是0,他并沒有存儲一個具有實際意義的指針。
含有純虛函數(shù)的類叫抽象類。哪怕只含有一個純虛函數(shù)也叫抽象類。
抽象類不允許實例化對象。
抽象類的子類也可以是抽象類。
抽象類的子類只有把抽象類當(dāng)中的所有純虛函數(shù)都做了實現(xiàn),這個子類才可以實例化對象。
查看全部 -
當(dāng)類中沒有虛函數(shù)的時候:
? ? ? ?我們通過類的對象訪問其數(shù)據(jù)成員,訪問其成員函數(shù);前面已經(jīng)知道,實例化對象時,只有數(shù)據(jù)成員的大小,這說明類的成員函數(shù)是統(tǒng)一放在內(nèi)存代碼區(qū)的,并且有自己的類名稱空間作為限制,只能自己實例化的對象訪問;所以我們通過對象訪問數(shù)據(jù)成員,是直接在對象的內(nèi)存塊中偏移得到;而通過對象訪問成員函數(shù),則是要到代碼區(qū)才能訪問到;
當(dāng)父類與子類之間有重名函數(shù)時:
(1)通過子類對象訪問父類該重名函數(shù)(于是有了隱藏):
? ? ? ? 父類與子類有重名函數(shù)時,這時出現(xiàn)了隱藏,即子類是繼承了父類的該重名函數(shù)的,但是將其隱藏了。通過子類對象訪問該函數(shù)時,訪問的是子類自己的該函數(shù),如果想要訪問父類的該函數(shù),則要在函數(shù)前面加上父類的名稱空間限定;代碼示例如下:父類Person和子類Worker,都有一個同名函數(shù)name();通過子類對象worker調(diào)用父類該函數(shù)時,worker.Person::name();
(2)通過父類指針指向子類對象,并訪問子類重名函數(shù)(于是有了虛函數(shù)):
? ? ? ? 父類指針指向子類對象時,父類指針只能訪問子類對象的數(shù)據(jù)成員(部分,繼承自父類的),和訪問父類在代碼區(qū)的自己的成員函數(shù);此時,如果想要通過父類指針訪問到子類對象的成員函數(shù)(即通過父類指針調(diào)用子類的析構(gòu)函數(shù)或者普通重名函數(shù)),就要將該重名函數(shù)設(shè)定為虛函數(shù),然后將虛函數(shù)地址放進該類的虛函數(shù)表中(于是有了覆蓋,即在子類虛函數(shù)表中用子類虛函數(shù)地址覆蓋掉父類虛函數(shù)地址),而對象又多了個數(shù)據(jù)成員(虛函數(shù)表指針),且在對象內(nèi)存塊首位;這樣當(dāng)我們用父類指針指向子類對象,且調(diào)用子類重名虛函數(shù)時,就要先在虛函數(shù)表中查找,如果找到,就執(zhí)行;即調(diào)用成員函數(shù)時,有虛函數(shù)表先在虛函數(shù)表中查找,然后再在代碼區(qū)查找;
? ? ? ? 這里我只解釋了父類指針訪問子類重名函數(shù)的情況,沒有解釋虛析構(gòu)函數(shù)不重名也能訪問的情況。我想可能是析構(gòu)函數(shù)有自己特殊的用法吧,可能每個類的析構(gòu)函數(shù)都是同一個名字,而在代碼中名字是不同的吧。這里如果有同學(xué)想明白了,希望能不吝賜教;
(3)通過子類對象初始化父類對象,通過父類對象不能訪問子類重名函數(shù)(虛):
? ? ? ? 按照上面的理論,子類對象初始化父類對象后,子類對象的數(shù)據(jù)成員會覆蓋掉父類對象的數(shù)據(jù)成員,但是這里,父類原有的虛函數(shù)表是沒有被覆蓋掉的,父類對象的虛函數(shù)表指針還是自己的表指針;表指針里的虛函數(shù)地址還是父類自己的虛函數(shù)地址,所以此時通過父類對象只能訪問到子類對象的數(shù)據(jù)成員(繼承自父類的),訪問自己代碼區(qū)的成員函數(shù)和虛函數(shù)列表中的自己的虛函數(shù),不能訪問到子類虛函數(shù)列表中的虛函數(shù);
查看全部 -
對象的大小
(1)類實例化對象時,對象的大小就是類中數(shù)據(jù)成員所占的內(nèi)存大?。〝?shù)據(jù)成員,不包含成員函數(shù));
(2)若類中存在一個或多個虛函數(shù)或虛析構(gòu)函數(shù),則會在實例對象的前4個B內(nèi)存單元存放一個虛函數(shù)表指針(指針大小為4B);
注意1:每個類只有一個虛函數(shù)表,所有該類的對象共用一張?zhí)摵瘮?shù)表。
注意2:父類和子類的虛函數(shù)表不同,但虛函數(shù)表中的函數(shù)地址可能相同,指向同一個虛函數(shù)地址(這種情況父類虛函數(shù)未被子類的覆蓋, 沒有形成多態(tài))
(3)如果類中沒有數(shù)據(jù)成員或虛函數(shù),則對象大小為1字節(jié),用來標(biāo)識對象的存在。
查看全部 -
沒有數(shù)據(jù)成員的類,實例化以后,sizeof后的值是1,原因是C++對于沒有數(shù)據(jù)成員的對象,C++會用1個內(nèi)存單元用來標(biāo)記這個對象
查看全部 -
對象的大小:類實例化的對象,數(shù)據(jù)成員占據(jù)的內(nèi)存大小,成員函數(shù)不占據(jù)內(nèi)存。
對象的地址:實例化的對象,所占內(nèi)存的第一個存儲單元的地址
對象成員地址:實例化對象有一個或多個數(shù)據(jù)成員,每個數(shù)據(jù)成員都有自己的地址,占一定的內(nèi)存空間(數(shù)據(jù)類型不同,地址不同)
虛函數(shù)表指針:具有虛函數(shù)的類實例化的對象時,對象的第一塊內(nèi)存中存儲的就是虛函數(shù)表指針
查看全部 -
通過虛析構(gòu)函數(shù),釋放父類指針就能夠釋放子類申請的內(nèi)存,有個理論前提就是:執(zhí)行完子類的虛構(gòu)函數(shù)就會執(zhí)行父類的析構(gòu)函數(shù)。因此只要保證能夠執(zhí)行子類的虛構(gòu)函數(shù)即可(就相當(dāng)于子類的和父類的都釋放了。 當(dāng)然,只有在堆內(nèi)申請內(nèi)存才會出現(xiàn)要釋放內(nèi)存的過程。)
父類指針指向子類的時候,訪問子類的虛函數(shù)列表,可以找到子類的虛析構(gòu)函數(shù),因此釋放父類指針可以執(zhí)行子類的虛析構(gòu)函數(shù)。反言之, 如果父類和子類的不是虛析構(gòu)函數(shù),則析構(gòu)函數(shù)不會存在與虛函數(shù)列表中,父類指針就找不到子類的析構(gòu)函數(shù)。
查看全部 -
函數(shù)的隱藏:定義了父類與子類,且出現(xiàn)了同名的函數(shù),稱為隱藏
函數(shù)的覆蓋:若在子類中未定義同名的虛函數(shù),則子類的虛函數(shù)表中寫上父類虛函數(shù)的入口地址;若在子類中定義了同名的虛函數(shù),則在子類的虛函數(shù)表中,子類虛函數(shù)入口地址覆蓋原來父類的
查看全部 -
虛函數(shù):假設(shè)存在、作為基類方便不同子類派生函數(shù)的存在函數(shù)。其特點在于,虛函數(shù)本身沒有任何意義,其只是作為一個象征:我所有的子類都有如此一個函數(shù)存在,至于子類的函數(shù)到底如何實現(xiàn),基類并不知曉。
查看全部 -
函數(shù)指針的實質(zhì)是指向這段函數(shù)代碼的開頭位置
查看全部 -
virtual在函數(shù)中的使用限制:
·普通函數(shù)不能是虛函數(shù)(編譯錯誤)
· 靜態(tài)成員函數(shù)不能是虛函數(shù)(編譯錯誤)
·內(nèi)聯(lián)函數(shù)不能是虛函數(shù)(可編譯,編譯器忽略inline關(guān)鍵字是函數(shù)變?yōu)榧兇馓摵瘮?shù))
·構(gòu)造函數(shù)不能是虛函數(shù)(編譯錯誤)
查看全部 -
子類的構(gòu)造與析構(gòu)原理--深入闡述虛析構(gòu)函數(shù)的重要性
查看全部 -
多態(tài)分為兩種 靜態(tài)多態(tài)和動態(tài)多態(tài)? 靜態(tài)指的就是函數(shù)重載(是在一個函數(shù)或者一個類中? )? ;而動態(tài)多態(tài)就是 指的多個類之間的多態(tài)??
查看全部 -
使用父類指針指向子類對象時,調(diào)用子類完全相同的函數(shù)時候 會執(zhí)行父類函數(shù),需要在父類加virtual關(guān)鍵字使父類函數(shù)成為虛函數(shù),才能調(diào)用子類自己的同名函數(shù)
查看全部 -
靜態(tài)多態(tài)(早綁定):成員函數(shù)同名,但參數(shù)數(shù)目不同時,調(diào)用成員函數(shù)使用的參數(shù)個數(shù)決定了啟用不同的成員函數(shù)。 /*函數(shù)編譯階段就已經(jīng)確定用哪種行為*/
動態(tài)多態(tài)(晚綁定):以封裝和繼承為基礎(chǔ),當(dāng)父類指針指向子類類型時,要用virtual去修飾子類中已經(jīng)重定義的成員函數(shù)(虛函數(shù)),否則使用的是父類的定義的成員函數(shù);子類中的同名成員函數(shù)virtual可加可不加,系統(tǒng)默認(rèn)補全。
”父類指針指向子類對象,通過父類指針只能尋址到從父類繼承到的成員函數(shù)與數(shù)據(jù)成員,子類擴展的將會被截斷。但是,如果將父類中同名函數(shù)設(shè)置為虛函數(shù),創(chuàng)建子類對象時將會創(chuàng)建子類自有的【虛函數(shù)表】,虛函數(shù)表指向的成員函數(shù)將覆蓋父類中的同名函數(shù)。“
查看全部 -
對不同對象下達相同指令,但是做的不同的操作
查看全部
舉報