什么是多態?
答:多態是多種形態,是為了完成某種行為時,不同對象會產生不同的形態(結合車票例子解釋)
2. 什么是重載、重寫(覆蓋)、重定義(隱藏)?
答:重載的條件是:在同一作用域下,同名函數的(參數個數,參數類型,參數順序不同)構成重載。
而重寫的條件是:在不同作用域下,(函數名,返回類型,參數列表)均相同,并且是虛函數構成的,叫做重寫
最后,重定義只要求不同作用域下,函數名相同的函數叫做重定義。兩個基類與派生類的同名函數,不是重寫就是重定義
3. 多態的實現原理?
答:多態分為靜態多態(編譯期間)和動態多態(運行期間)
而靜態多態:傳不同參數。調用不同函數。自動識別類型,根據函數名修飾規則(比如像函數重載,編譯時進行匹配,過了之后,如果走到鏈接的時候,通過函數名修飾規則去找)去尋找對應的變量
而動態多態:傳不同對象,調不同函數。(繼承中虛函數重寫+父類指針調用)就通過生成虛函數表,做到指向哪個類,就去哪個類的對象的虛函數表找。即指向誰就調用誰
4. inline函數可以是虛函數嗎?
答:可以,不過編譯器就忽略inline屬性,這個函數就不再是inline,因為虛函數要放到虛表中去。
5. 靜態成員可以是虛函數嗎?
答:不能,因為靜態成員函數沒有this指針,使用類型::成員函數的調用方式無法訪問虛函數表,所以靜態成員函數無法放進虛函數表。
6. 構造函數可以是虛函數嗎?
答:不能,因為對象中的虛函數表指針是在構造函數初始化列表階段才初始化的。
形象地說就是:先有雞還是先有蛋?調構造函數,如果是虛函數,虛函數的目的就是實現多態,那么實現要多態,你連虛表都沒有,你去哪里找虛函數地址?因此對象初始化好了才有虛表,通過虛表找虛函數。
7. 析構函數可以是虛函數嗎?什么場景下析構函數是虛函數?
答:可以,并且最好把基類的析構函數定義成虛函數。基類只要定義了虛函數,那么派生類的析構函數都會與基類的析構函數構成重寫,其中它的內部原理是統一變成一個叫destructor的函數名。來保證對象的正確銷毀,做到先釋放派生類,再去釋放基類的順序。
8. 對象訪問普通函數快還是虛函數更快?
答:首先得分情況:如果是普通對象,是一樣快的。如果是指針對象或者是引用對象,則調用的普通函數快,因為構成多態,運行時調用虛函數需要到虛函數表中去查找。
9. 虛函數表是在什么階段生成的,存在哪的?
答:虛函數表是在編譯階段就生成的,一般情況下存在代碼段(常量區)的。(+多態那篇文章里的證明)
10. C++菱形繼承的問題?虛繼承的原理?
答:C++的菱形繼承會存在二義性和冗余性。
而虛繼承就是為了解決上面的問題的:通過一個虛基表,虛基表存的是基類偏移量的表,通過虛基表計算變量在對象里面的地址,再隨著地址去訪問
11. 什么是抽象類?抽象類的作用?
答:抽象類就是在虛函數后面寫=0;抽象類強制重寫了虛函數,另外抽象類體現出了接口繼承關系。
最后到了本次雞湯:
?
?