C++多态面试题汇总
總結(jié)了一些常見(jiàn)的面試題,通過(guò)查閱資料給出了一些淺薄的解析,歡迎各位批評(píng)指教。
1. inliine函數(shù)可以實(shí)虛函數(shù)碼?
不可以,因?yàn)閕nline函數(shù)沒(méi)有地址,無(wú)法將他存放到虛函數(shù)表中。
2. 靜態(tài)成員可以是虛函數(shù)嗎?
不能,因?yàn)殪o態(tài)成員函數(shù)中沒(méi)有this指針,使用::成員函數(shù)的嗲用用方式無(wú)法訪問(wèn)虛函數(shù)表,所以靜態(tài)成員函數(shù)無(wú)法放進(jìn)虛函數(shù)表。
3. 構(gòu)造函數(shù)可以是虛函數(shù)嗎?
不可以,因?yàn)閷?duì)象中的虛函數(shù)指針是在對(duì)象構(gòu)造的時(shí)候初始化的。
4. 析構(gòu)函數(shù)可以是虛函數(shù)嗎?什么場(chǎng)景下析構(gòu)函數(shù)是虛函數(shù)?
可以,最好將析構(gòu)函數(shù)設(shè)置為虛函數(shù)最好是將父類(lèi)的析構(gòu)函數(shù)設(shè)置為虛函數(shù) ,因?yàn)檫@樣可以避免內(nèi)存泄漏的問(wèn)題。如果一個(gè)父類(lèi)的指針指向了子類(lèi)的的對(duì)象,并且父類(lèi)的虛函數(shù)沒(méi)有設(shè)置成虛函數(shù),那么子類(lèi)對(duì)象中的虛函數(shù)就沒(méi)有實(shí)現(xiàn)多態(tài),他只會(huì)調(diào)用父類(lèi)的析構(gòu)函數(shù),不會(huì)調(diào)用子類(lèi)的析構(gòu)函數(shù),但是他創(chuàng)建對(duì)象的時(shí)候調(diào)用了子類(lèi)的構(gòu)造函數(shù),所以說(shuō)就用子類(lèi)的構(gòu)造函數(shù)就應(yīng)該該取調(diào)用他的析構(gòu)函數(shù),這樣才能保證所有的必須釋放的資源都是放了,才可以保證不會(huì)有內(nèi)存泄漏。如果是多態(tài)的,就會(huì)先去調(diào)用子類(lèi)的析構(gòu)函數(shù),然后再取調(diào)用父類(lèi)的析構(gòu)函數(shù),這樣子類(lèi)和父類(lèi)的資源就都可以釋放。
5. 對(duì)象訪問(wèn)普通函數(shù)快還是虛函數(shù)快?
如果是普通對(duì)象,是一樣快的,如果是指針對(duì)象或者是引用對(duì)象,調(diào)用普通函數(shù)更快一些,因?yàn)闃?gòu)成了多態(tài),運(yùn)行時(shí)調(diào)用虛函數(shù)要先到虛函數(shù)表中去查找。這樣然后才拿到韓式的地址,這樣就不如直接可以拿到函數(shù)地址的普通函數(shù)快。
6. 虛函數(shù)表時(shí)再什么階段生成的?他存放在哪里?
虛函數(shù)時(shí)再編譯階段生成的,他一般存放再代碼段,也就是常量區(qū)。
7. 執(zhí)行下面這段代碼的結(jié)果
#include <iostream> using namespace std;class Base { public:virtual void x(){cout << "Base::x" << endl;}void y(){x();cout << "Base::y" << endl;} };class Derive : public Base { public:virtual void x(){cout << "Derive::x" << endl;}void y(){cout << "Derive::y" << endl;} };int main() {Base* p = new Derive;p->y();return 0; }解析:很顯然Derive繼承了Base,并且實(shí)現(xiàn)了多態(tài),但是只有x()是虛函數(shù)重寫(xiě),y()只在子類(lèi)中聲明了虛函數(shù),沒(méi)有在父類(lèi)中聲名所以不能y()不是虛函數(shù)重寫(xiě),而是對(duì)父類(lèi)中的y()重定義,所以在p調(diào)用y()的時(shí)候直接調(diào)用Base中的y(),在Base的y()中調(diào)用了x(),由于x()在子類(lèi)中構(gòu)成了虛函數(shù)重寫(xiě),所以調(diào)用子類(lèi)中的x(),答案也就不曉而知了。
8. 是否可以將類(lèi)中的所有成員函數(shù)都聲明稱(chēng)為虛函數(shù),為什么?
虛函數(shù)是在程序運(yùn)行的時(shí)候通過(guò)尋址操作才能確定真正要調(diào)用的的函數(shù),而普通的成員函數(shù)在編譯的時(shí)候就已經(jīng)確定了要調(diào)用的函數(shù)。這個(gè)兩者的區(qū)別,從效率上來(lái)說(shuō),虛函數(shù)的效率要低于普通成員函數(shù),因?yàn)樘摵瘮?shù)要先通過(guò)對(duì)象中的虛標(biāo)指針拿到虛函數(shù)表的地址,然后再?gòu)奶摵瘮?shù)表中找到對(duì)應(yīng)的函數(shù)地址,最后根據(jù)函數(shù)地址去調(diào)用,而普通成員函數(shù)直接就可以拿到地址進(jìn)行調(diào)用,所以沒(méi)必要將所有的成員函數(shù)聲明成虛函數(shù)。
9. 虛函數(shù)表指針被編譯器初始化的過(guò)程怎么理解的?
當(dāng)類(lèi)中聲明了虛函數(shù)是,編譯器會(huì)在類(lèi)中生成一個(gè)虛函數(shù)表VS中存放在代碼段,虛函數(shù)表實(shí)際上就是一個(gè)存放虛函數(shù)指針的指針數(shù)組,是由編譯器自動(dòng)生成并維護(hù)的。虛表是屬于類(lèi)的,不屬于某個(gè)具體的對(duì)象,一個(gè)類(lèi)中只需要有一個(gè)虛表即可。同一個(gè)類(lèi)中的所有對(duì)象使用同一個(gè)虛表,為了讓每個(gè)包含虛表的類(lèi)的對(duì)象都擁有一個(gè)虛表指針,編譯器在每個(gè)對(duì)象的頭添加了一個(gè)指針,用來(lái)指向虛表,并且這個(gè)指針的值會(huì)自動(dòng)被設(shè)置成指向類(lèi)的虛表,每一個(gè)virtaul函數(shù)的函數(shù)指針存放在虛表中,如果是單繼承,先將父類(lèi)的虛表添加到子類(lèi)的虛表中,然后子類(lèi)再添加自己新增的虛函數(shù)指針,但是在VS編譯器中我們通常看不到新添加的虛函數(shù)指針,是編譯器故意將他們隱藏起來(lái),如果是多繼承,在子類(lèi)中新添加的虛函數(shù)指針會(huì)存放在第一個(gè)繼承父類(lèi)的虛函數(shù)表中。
10. 多態(tài)的分類(lèi)?
靜態(tài)綁定的多態(tài)的是通過(guò)函數(shù)的重載來(lái)實(shí)現(xiàn)的。動(dòng)態(tài)綁定的多態(tài)是通過(guò)虛函數(shù)實(shí)現(xiàn)的。
11. 為什么要引入抽象類(lèi)和純虛函數(shù)?
為了方便使用多態(tài)特性,在很多情況下由基類(lèi)生成對(duì)象是很不合理的,純虛函數(shù)在基類(lèi)中是沒(méi)有定義的,要求在子類(lèi)必須加以實(shí)現(xiàn),這種包含了純虛函數(shù)的基類(lèi)被稱(chēng)為抽象類(lèi),不能被實(shí)例化,如果子類(lèi)沒(méi)有實(shí)現(xiàn)純虛函數(shù),那么它他也是一個(gè)抽象類(lèi)。
12. 虛函數(shù)和純虛函數(shù)有什么區(qū)別?
從基類(lèi)的角度出發(fā),如果一個(gè)類(lèi)中聲明了虛函數(shù),這個(gè)函數(shù)是要在類(lèi)中實(shí)現(xiàn)的,它的作用是為了能讓這個(gè)函數(shù)在他的子類(lèi)中能被重寫(xiě),實(shí)現(xiàn)動(dòng)態(tài)多態(tài)。純虛函數(shù),只是一個(gè)接口,一個(gè)函數(shù)聲明,并沒(méi)有在聲明他的類(lèi)中實(shí)現(xiàn)。對(duì)于子類(lèi)來(lái)說(shuō)它可以不重寫(xiě)基類(lèi)中的虛函數(shù),但是他必須要將基類(lèi)中的純虛函數(shù)實(shí)現(xiàn)。虛函數(shù)既繼承接口的同時(shí)也繼承了基類(lèi)的實(shí)現(xiàn),純虛函數(shù)關(guān)注的是接口的統(tǒng)一性,實(shí)現(xiàn)完全由子類(lèi)來(lái)完成。
13. 什么是多態(tài)?他有什么作用?
多態(tài)就是一個(gè)接口多種實(shí)現(xiàn),多態(tài)是面向?qū)ο蟮娜筇匦灾弧6鄳B(tài)分為靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)。靜態(tài)多態(tài)包含函數(shù)重載和泛型編程,進(jìn)程多態(tài)是程序調(diào)用函數(shù),編譯器決定使用哪個(gè)可執(zhí)行的代碼塊。靜態(tài)多態(tài)是由繼承機(jī)制以及虛函實(shí)現(xiàn)的,通過(guò)指向派生類(lèi)的基類(lèi)指針或者引用,訪問(wèn)派生類(lèi)中同名重寫(xiě)成員函數(shù)。墮胎的作用就是把不同子類(lèi)對(duì)象都當(dāng)作父類(lèi)來(lái)看,可以屏蔽不同子類(lèi)之間的差異,從而寫(xiě)出通用的代碼,做出通用的編程,以適應(yīng)需求的不斷變化。
總結(jié)
以上是生活随笔為你收集整理的C++多态面试题汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【每日SQL打卡】
- 下一篇: C++常见面试题(2019年校招总结)