C++面試題(五)

C++的空類,默認產生哪些類成員函數?
答:

class Empty
{
 public:
Empty();                           //缺省構造函數
Emptyconst Empty& );           //拷貝構造函數
~Empty();                          //虛構函數
Empty& operator(const Empty& )     //賦值運算符
}

簡單敘述面向對象的三個基本特徵

答:封裝性即把客觀事物封裝成抽象的類,對自身的數據和方法進行(publicprivateprotected)
繼承性
繼承概念的實現方式有三類:實現繼承、接口繼承和可視繼承。
實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;
接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實現的能力;
可視繼承是指子窗體(類)使用基窗體(類)的外觀和實現代碼的能力。
抽象類僅定義將由子類創建的一般屬性和方法,創建抽象類時,請使用關鍵字 Interface 而不是 Class
多態性
多態性(polymorphisn)是允許你將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值之後,
父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。允許將子類類型的指針賦值給父類類型的指針。
實現多態,有二種方式,覆蓋(子類重新定義父類的虛函數),重載(允許存在多個同名函數,參數個數,類型不同)。

C++中哪些函數不能被聲明爲虛函數?

答:普通函數(非成員函數),構造函數,內聯成員函數、靜態成員函數、友元函數。
(1)虛函數用於基類和派生類,普通函數所以不能
(2)構造函數不能是因爲虛函數採用的是虛調用的方法,允許在只知道部分信息的情況的工作機制,
特別允許調用只知道接口而不知道對象的準確類型的方法,但是調用構造函數即使要創建一個對象,
那勢必要知道對象的準確類型。
(3)內聯成員函數的實質是在調用的地方直接將代碼擴展開
(4)繼承時,靜態成員函數是不能被繼承的,它只屬於一個類,因爲也不存在動態聯編等
(5)友元函數不是類的成員函數,因此也不能被繼承

C++編譯器自動爲類產生的四個確缺省函數是什麼?

答:默認構造函數,拷貝構造函數,析構函數,賦值函數

構造函數可否是虛汗數,爲什麼?析構函數呢,可否是純虛的呢?

答:
構造函數不能爲虛函數,要構造一個對象,必須清楚地知道要構造什麼,否則無法構造一個對象。
析構函數可以爲純虛函數

構造函數和析構函數的調用順序? 析構函數爲什麼要虛擬?

答案:構造函數的調用順序:基類構造函數—對象成員構造函數—派生類構造函數;析構函數的調用順序與構造函數相反。析構函數虛擬是爲了防止析構不徹底,造成內存的泄漏。

是不是一個父類寫了一個 virtual 函數,如果子類覆蓋它的函數不加 virtual , 也能實現多態 ?

答: virtual 修飾符會被隱形繼承的。 private  也被繼承,只是派生類沒有訪問權限而已。 virtual 可加可不加。子類的空間裏有父類的所有變量 (static 除外 ) 。同一個函數只存在一個實體 (inline 除外 ) 。子類覆蓋它的函數不加 virtual , 也能實現多態。在子類的空間裏,有父類的私有變量。私有變量不能直接訪問

當一個類A 中沒有生命任何成員變量與成員函數,這時sizeof(A)的值是多少,請解釋一下編譯器爲什麼沒有讓它爲零。

答案:爲1。舉個反例,如果是零的話,聲明一個class A[10]對象數組,而每一個對象佔用的空間是零,這時就沒辦法區分A[0],A[1]…了

怎樣消除多重繼承中的二義性?

答: 1.成員限定符  2.虛基類

什麼叫靜態關聯,什麼叫動態關聯

答:在多態中,如果程序在編譯階段就能確定實際執行動作,則稱靜態關聯,
如果等到程序運行才能確定叫動態關聯。

多態的兩個必要條件

答:1.一個基類的指針或引用指向一個派生類對象  2.虛函數

什麼時候需要用虛析構函數?

答:當基類指針指向用new運算符生成的派生類對象時,delete基類指針時,派生類部分沒有釋放掉而造成釋放不徹底現象,需要虛析構函數。 補充:虛函數就是讓派生類調用基類的虛函數。

13.怎樣定義一個純虛函數?含有純虛函數的類稱爲什麼?

答:在虛函數的後面加=0,含有虛函數的類稱爲抽象類。

什麼時候必須重寫拷貝構造函數?

答:當構造函數涉及到動態存儲分配空間時,要自己寫拷貝構造函數,並且要深拷貝。

構造函數的調用順序是什麼?

答:1.先調用基類構造函數
2.按聲明順序初始化數據成員
3.最後調用自己的構造函數。

構造函數和析構函數是否可以被重載,爲什麼?

答:構造函數可以被重載,析構函數不可以被重載。因爲構造函數可以有多個且可以帶參數,而析構函數只能有一個,且不能帶參數。

說一下 C++ 中 static_cast 和 dynamic_cast 的區別。

答: static_cast  用於有比較明確定義的變換,包括不需要強制轉換的變換。
dynamic_cast  適用於類型安全的向下轉換,常用在繼承中的父類指針向子類指針的轉換。若轉換成功則返回改類型的指針,若失敗,則返回 NULL 

類成員函數的重載、覆蓋和隱藏區別?


答:
a. 成員函數被重載的特徵:
( 1 )相同的範圍(在同一個類中);
( 2 )函數名字相同;
( 3 )參數不同;
( 4virtual  關鍵字可有可無。
b. 覆蓋是指派生類函數覆蓋基類函數,特徵是:
( 1 )不同的範圍(分別位於派生類與基類);
( 2 )函數名字相同;
( 3 )參數相同;
( 4 )基類函數必須有 virtual  關鍵字。
c. “隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規則如下:
( 1 )如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無 virtual 關鍵字,基類的函數將被隱藏(注意別與重載混淆)。
( 2 )如果派生類的函數與基類的函數同名,並且參數也相同,但是基類函數沒有 virtual  關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)
#i nclude 
using namespace std;
class Base
{
public: 
virtual ~Base() { cout "~Base" endl ; }
};
class Derived : public Base
{
public: 
virtual ~Derived() { cout "~Derived" endl ; }
};
void main(void)
{
Base * pB = new Derived; // upcast
delete pB;
cin.get();
}

//輸出結果爲:
~Derived
~Base
//如果析構函數不爲虛,那麼輸出結果爲
~Base
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章