C++常見面試問題

Q1:構造函數可以是虛函數嗎?爲什麼?
A1:不可以。
從實現上,虛函數是使用虛表指針,而虛表指針存在於對象的內存空間中,而在構造函數調用之前,對象內存空間還沒有分配,所以不存在使用虛表指針調用構造函數。
從使用角度上,虛函數的作用在於通過父類的指針或者引用來調用它的時候能夠變成調用子類的那個成員函數。而構造函數是在創建對象時自動調用的,不可能通過父類的指針或者引用去調用。
Q2:析構函數可以是純虛函數嗎?
A2:可以。
但是作爲基類時需要給出定義,否則連接會出錯;因爲在調用派生類析構函數後,總會調用基類的析構函數。
class Fruit{
public:
    Fruit(){};
    virtual ~Fruit()=0;
};
Fruit::~Fruit(){}
Q3:析構函數可以重載嗎?爲什麼?
A3:不可以,因爲析構函數沒有參數列表。
Q4:純虛函數可以有函數體嗎?
A4:可以,但是沒有意義。
Q5:析構函數爲什麼一般情況下要聲明爲虛函數?
A5:可以使用基類指針指向派生類的對象,當刪除該指針(delete p),如果析構函數不被聲明成虛函數,則編譯器實施靜態綁定,在刪除基類指針時,只會調用基類的析構函數而不調用派生類析構函數,這樣就會造成派生類對象析構不完全。如果析構函數被聲明爲虛函數,就會調用該指針指向的派生類析構函數,而派生類的析構函數又自動調用基類的析構函數,這樣整個派生類的對象完全被釋放。所以,將析構函數聲明爲虛函數是十分必要的。
Q6:在基類中將析構函數定義成虛函數的作用是什麼?
A6:當通過基類指針刪除一個派生類的對象時,派生類的析構函數能夠被調用。
Q7:如果虛函數是非常有效的,我們是否可以把每個函數都聲明爲虛函數?
A7:不可以,使用虛函數會產生系統開銷,因爲需要維護虛函數表;如果一個類不需要派生其他類,根本沒有必要使用虛函數。
Q8:什麼情況下必須定義拷貝構造函數?
A8:當類的對象用於函數值傳遞時(值參數,返回類對象),拷貝構造函數會被調用。如果對象複製並非簡單的值拷貝,那就必須定義拷貝構造函數。
Q9:指針和引用的區別有哪些?
A9:
1.指針是一個變量,會分配內存空間;而引用是變量的別名,跟變量是同一個東西,所以不分配內存空間。
2.引用必須在定義是初始化,而且以後不能改變;而指針不是。
3.引用不能爲NULL,而指針可以。
4.引用訪問一個變量是直接訪問,而指針是間接訪問。
5.sizeof引用得到變量的大小,而sizeof指針是得到指針本身的大小。
Q10:能不能同時用static和const修飾類的成員函數?
A10:不可以。
C++編譯器在實現const的成員函數的時候爲了確保該函數不能修改類的實例的狀態,會在函數中添加一個隱含的參數const this*。但是靜態成員函數是沒有this指針參數的。也就是說static的用法和const是衝突的。
Q11:靜態成員函數能不能是同時也是虛函數?
A11 :不能。
調用靜態成員函數不需要實例。但調用虛函數需要訪問實例的虛表指針,通過虛表指針找到虛函數表以得到函數的地址,因此調用虛函數需要一個實例。兩者相互矛盾。
Q12:重載(overload)和重寫(override)的區別是什麼?
A12:重載是在同一作用域中,函數名相同,但是參數類型、個數等不完全相同;
重寫是在不同作用域中(基類和派生類),函數名和參數列表完全相同,並且該函數爲虛函數
以下兩種情況不是重寫,而是隱藏
1.派生類函數與基類函數名稱與參數列表完全相同,但是基類函數不是虛函數;
2. 派生類函數與基類函數名稱相同但是參數列表不同,無論基類函數是不是虛函數。
Q13:類內可以重載new和delete運算符嗎?如果可以的話,重載的函數可以是static的嗎?
A13:當然可以;重載的函數無論是否加上static,都是static的。因爲new對象時,對象還沒有,所以要聲明爲static函數。delete對象也一樣。
Q14:類中的靜態屬性會影響sizeof的值嗎?
A14:不會的。sizeof(T)時,只考慮分配對象時需要的空間大小。
Q15:什麼是虛擬繼承?
A15:虛擬繼承使得派生類如果繼承基類多次,但只有一份基類的拷貝在派生類對象中。
發佈了102 篇原創文章 · 獲贊 8 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章