-
virtual 不能修飾普通函數
virtual不能修飾靜態成員函數
virtual不能修飾內聯函數(會忽略掉inline而成為虛函數)
構造函數不能為虛函數
查看全部 -
當父類定義一個虛函數時,隨即創建了一個虛函數表指針
查看全部 -
靜態綁定(早綁定):在編譯階段已經確定使用哪一個函數
動態多態(晚綁定):以封裝和繼承為基礎,用虛函數實現
查看全部 -
純虛函數不能實例化對象,但可以指向子類地址!!!
查看全部 -
我們可以為純虛函數提供定義,不過函數體必須定義在類的外部。若定義在類的內部,會出現錯誤
查看全部 -
VIRTUAL只需要加在父類里邊(析構函數和同名成員函數)就好,析構函數前邊加是為了防止沒有釋放子類對象的內存導致內存泄露,同名成員函數前加是為了父類實例化的對象指針能夠指向子類數據成員。
如果我們沒有在子類當中定義同名的虛函數,那么在子類虛函數表中就會寫上父類的虛函數的函數入口地址;如果我們在子類當中也定義了虛函數,那么在子類的虛函數表中我們就會把原來的父類的虛函數的函數地址覆蓋一下,覆蓋成子類的虛函數的函數地址,這種情況就稱之為函數的覆蓋。
查看全部 -
虛函數實現多態的原理:
虛函數表指針(指向了虛函數表的首地址)->虛函數表(地址的偏移找到對應的虛函數的地址)->虛函數。
在父類指針指向子類實例時:
? 如果子類中沒有定義相同名稱的虛函數,就會從從父類中繼承了,所以在實例化時會產生一個虛函數表(跟父類中的不是同一個,即虛函數表指針不同),但是相應函數(比如計算面積)的函數指針是一樣的(同樣的入口地址)。
? 如果在子類中定義了同名的虛函數,就會在子類的虛函數列表中將父類中定義的虛函數的函數地址覆蓋掉,從而實現多態。
【虛析構函數的原理】:通過父類類指針指向子類實例的內存空間,找到子類的虛函數表指針所指向的虛函數表,然后在表中找到虛析構函數地址,從而找到虛析構函數執行子類的虛析構函數,再自動執行父類的虛析構函數。
補充1:理論前提,執行完子類的析構函數后,會執行父類的析構函數。
補充2:C++中的虛函數的作用主要是實現了多態的機制。關于多態,簡而言之就是用父類型別的指針指向其子類的實例,然后通過父類的指針調用實際子類的成員函數。
這種技術可以讓父類的指針有“多種形態”,這是一種泛型技術。所謂泛型技術,說白了就是試圖使用不變的代碼來實現可變的算法。
?比如:模板技術,RTTI技術,虛函數技術,要么是試圖做到在編譯時決議,要么試圖做到運行時決議。
查看全部 -
虛函數特性可以被繼承,當子類中定義的函數與父類中虛函數的聲明相同時,該函數也是虛函數。只是平時我們都習慣在子類的虛函數前面也加上virtual關鍵字。
查看全部 -
并不是所有的都加上virtual就完事了。
1、使用virtual會產生一個虛擬指針表,要維持這個表,便額外加大了系統的開銷。
2、也不是所有的成員函數都需要實現多態的,總有些函數實現的功能意義時固定的,比如說加減乘除
3、虛繼承無非是為了避免諸如菱形繼承的情況,在我們構建類圖的時候,就需要考慮到這些問題,如果能不用虛繼承,就不用咯。
綜上,應該是能不用就不用,C++就是以號稱節省資源,運行效率高的。如果在寫程序的時候,使得消耗過多的系統資源,便失去了這門語言高效的意義了。那還不如直接用一些新興的語言如GO,SCALA之類的了。
查看全部 -
Shape 類的析構函數前 如果沒加virtual,則只會執行父類的 析構函數,如果加了 virtual,則先執行子類的析構函數,在執行父類的析構函數。
如果加了 virtual 父類就會通過虛函數表 和虛函數表指針 找到子類的析構函數 從而釋放掉子類對象。
查看全部 -
虛函數=0就是純虛函數
含有純虛函數的類叫做抽象類
抽象類無法實例化對象
查看全部 -
覆蓋只是在虛函數列表中將函數指針替換掉。 如果通過類去訪問,還是可以訪問的。
覆蓋僅指父類中有virtual修飾的函數且子類中剛好有同名函數,則發生覆蓋,
使用父類指針指向子類對象時,指向的是繼承的成員函數,而子類對象特有的部分,父類對象無法實現訪問。
查看全部 -
父類有虛析構函數,子類會繼承虛析構函數
有虛析構函數的class創建的對象里有虛函數指針,占4個內存單元,虛函數指針指向虛函數表,虛函數指針的值是虛函數表的地址。
查看全部 -
虛析構函數是為了避免使用父類指針釋放子類對象時造成內存泄露
查看全部 -
virtrual 不能修飾:
1普通函數
2靜態函數static
3內聯函數inline
4構造函數
查看全部
舉報