C++面試題(一)

 什麼函數不能聲明爲虛函數

1:非類的成員函數;

2:靜態成員函數; 

3:內聯函數; 

4:構造函數;

 

全局變量和局部變量在內存中是否有區別?如果有,是什麼區別

全局變量儲存在靜態數據區,局部變量在堆棧中。

 

引用與指針有什麼區別

1. 指針是一個實體,而引用僅是個別名;

2. 引用只能在定義時被初始化一次,之後不可變;指針可變;

3. 引用不能爲空,指針可以爲空;

4. 引用沒有 const,指針有 const;

 

處理器標識#error的目的是什麼?

答:編譯時輸出一條錯誤信息,並中止繼續編譯。

簡述數組與指針的區別

數組要麼在靜態存儲區被創建(如全局數組),要麼在棧上被創建。指針可以隨時指向任意類型的內存塊。

(1)修改內容上的差別

char a[] =“hello”;

a[0] = ‘X’;

char *p = “world”;// 注意p 指向常量字符串

p[0] = ‘X’; // 編譯器不能發現該錯誤,運行時錯誤

(2) 用運算符sizeof 可以計算出數組的容量(字節數)。sizeof(p),p 爲指針得到的是一個指針變量的字節數,而不是p 所指的內存容量。C++/C 語言沒有辦法知道指針所指的內存容量,除非在申請內存時記住它。注意當數組作爲函數的參數進行傳遞時,該數組自動退化爲同類型的指針。

char a[] ="hello world";

char *p = a;

cout<<sizeof(a) << endl; // 12字節

cout<<sizeof(p) << endl; // 4 字節

計算數組和指針的內存容量

void Func(chara[100])

{

cout<<sizeof(a) << endl; // 4 字節而不是100 字節

}

 

 

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

a.成員函數被重載的特徵:

(1)相同的範圍(在同一個類中);

(2)函數名字相同;

(3)參數不同;

(4)virtual 關鍵字可有可無。

b.覆蓋是指派生類函數覆蓋基類函數,特徵是:

(1)不同的範圍(分別位於派生類與基類);

(2)函數名字相同;

(3)參數相同;

(4)基類函數必須有virtual 關鍵字。

c.“隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規則如下:

(1)如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)。

(2)如果派生類的函數與基類的函數同名,並且參數也相同,但是基類函數沒有virtual關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)

 

 有哪幾種情況只能用intialization list 而不能用assignment

答案:

當類中含有const、reference 成員變量;

基類的構造函數。

類的成員是對象成員初始化,而該對象沒有無參構造函數。

 

 不允許重載的5個運算符是哪些?

答:

1.   .*(成員指針訪問運算符號)

2.   ::域運算符

3.   Sizeof 長度運算符號

4.   ?:條件運算符號

5.  .(成員訪問符)

 

流運算符爲什麼不能通過類的成員函數重載?一般怎麼解決?

答:因爲通過類的成員函數重載必須是運算符的第一個是自己,而對流運算的重載要求第一個參數是流對象。所以一般通過友元來解決。

 

對對象成員進行初始化的次序是什麼?

答:它的次序完全不受它們在初始化表中次序的影響,只有成員對象在類中聲明的次序來決定的。

 

類和對象之間的關係是什麼?

答:類是對象的抽象,對象是類的實例。

 

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

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

 

對象間是怎樣實現數據的共享的?

答:通過類的靜態成員變量來實現對象間的數據共享。靜態成員變量佔有自己獨立的空間不爲某個對象所私有。

 

main 函數執行以前,還會執行什麼代碼?

答案:全局對象的構造函數會在main函數之前執行。

 

C++中類型爲private的成員變量可以由哪些函數訪問?

答:只可以由本類中的成員函數和友元函數訪問

 

在類外有什麼辦法可以訪問類的非公有成員?

答:友元,繼承,調用公有成員函數。

 

strcpy()和memcpy()的區別?

答:strcpy()和memcpy()都可以用來拷貝字符串,strcpy()拷貝以’\0’結束,但memcpy()必須指定拷貝的長度。

 

 總結static的應用和作用?

答:(1)函數體內static變量的作用範圍爲該函數體,不同於auto變量,該變量的內存只被分配一次,因此其值在下次調用時仍維持上次的值;
(2)在模塊內的static全局變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問;
(3)在模塊內的static函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明它的模塊內;
(4)在類中的static成員變量屬於整個類所擁有,對類的所有對象只有一份拷貝;
(5)在類中的static成員函數屬於整個類所擁有,這個函數不接收this指針,因而只能訪問類的static成員變量。

 

 class 和 struct 的區別?

答:struct 的成員默認是公有的,而類的成員默認是私有的。

 

簡述枚舉類型?

答:枚舉方便一次定義一組常量,使用起來很方便;

 

assert()的作用?

答:ASSERT()是一個調試程序時經常使用的宏,在程序運行時它計算括號內的表達式,如果表達式爲FALSE (0), 程序將報告錯誤,並終止執行。如果表達式不爲0,則繼續執行後面的語句。這個宏通常原來判斷程序中是否出現了明顯非法的數據,如果出現了終止程序以免導致嚴重後果,同時也便於查找錯誤。

 

 類的聲明和實現的分開的好處?

答:1.   起保護作用;

2.   提高編譯的效率。

 

 

總結const的應用和作用?

答:(1)欲阻止一個變量被改變,可以使用const關鍵字。在定義該const變量時,通常需要對它進行初始化,因爲以後就沒有機會再去改變它了;

(2)對指針來說,可以指定指針本身爲const,也可以指定指針所指的數據爲const,或二者同時指定爲const;

(3)在一個函數聲明中,const可以修飾形參,表明它是一個輸入參數,在函數內部不能改變其值;

(4)對於類的成員函數,若指定其爲const類型,則表明其是一個常函數,不能修改類的成員變量;

(5)對於類的成員函數,有時候必須指定其返回值爲const類型,以使得其返回值不爲“左值”。

 

 

在類的內部定義成員函數的函數體,這種函數會具備那種屬性?

答:這種函數會自動爲內聯函數,這種函數在函數調用的地方在編譯階段都會進行代碼替換。

 

 成員函數通過什麼來區分不同對象的成員數據?爲什麼它能夠區分?

答:通過this指針指向對象的首地址來區分的。

 

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

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

 

拷貝構造函數在哪幾種情況下會被調用?

答:

1.當類的一個對象去初始化該類的另一個對象時;

2.如果函數的形參是類的對象,調用函數進行形參和實參結合時;

3.如果函數的返回值是類對象,函數調用完成返回時。

 

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

答:1.先調用基類構造函數

2.按聲明順序初始化數據成員

3.最後調用自己的構造函數。

 

 C++是不是類型安全的?

答案:不是。兩個不同類型的指針之間可以強制轉換(用reinterpret cast)。C#是類型安全的。

 

main 函數執行以前,還會執行什麼代碼?

答案:全局對象的構造函數會在main 函數之前執行。

 

描述內存分配方式以及它們的區別?

1) 從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static 變量。

2) 在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集。

3) 從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc 或new 申請任意多少的內存,程序員自己負責在何時用free 或delete 釋放內存。動態內存的生存期由程序員決定,使用非常靈活,但問題也最多。

 

new、delete、malloc、free關係

delete會調用對象的析構函數,和new對應free只會釋放內存,new調用構造函數。malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用於申請動態內存和釋放內存。對於非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以及一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。

 

delete與 delete []區別

對於內建簡單數據類型,delete和delete[]功能是相同的。對於自定義的複雜數據類型,delete和delete[]不能互用。delete[]刪除一個數組,delete刪除一個指針。簡單來說,用new分配的內存用delete刪除;用new[]分配的內存用delete[]刪除。delete[]會調用數組元素的析構函數。內部數據類型沒有析構函數,所以問題不大。如果你在用delete時沒用括號,delete就會認爲指向的是單個對象,否則,它就會認爲指向的是一個數組。

 

多態,虛函數,純虛函數

多態:是對於不同對象接收相同消息時產生不同的動作。C++的多態性具體體現在運行和編譯兩個方面:在程序運行時的多態性通過繼承和虛函數來體現;

在程序編譯時多態性體現在函數和運算符的重載上;

虛函數:在基類中冠以關鍵字 virtual 的成員函數。 它提供了一種接口界面。允許在派生類中對基類的虛函數重新定義。

純虛函數的作用:在基類中爲其派生類保留一個函數的名字,以便派生類根據需要對它進行定義。作爲接口而存在 純虛函數不具備函數的功能,一般不能直接被調用。

從基類繼承來的純虛函數,在派生類中仍是虛函數。如果一個類中至少有一個純虛函數,那麼這個類被稱爲抽象類(abstract class)。

抽象類中不僅包括純虛函數,也可包括虛函數。抽象類必須用作派生其他類的基類,而不能用於直接創建對象實例。但仍可使用指向抽象類的指針支持運行時多態性。

 

將“引用”作爲函數參數有哪些特點

(1)傳遞引用給函數與傳遞指針的效果是一樣的。這時,被調函數的形參就成爲原來主調函數中的實參變量或對象的一個別名來使用,所以在被調函數中對形參變量的操作就是對其相應的目標對象(在主調函數中)的操作。

(2)使用引用傳遞函數的參數,在內存中並沒有產生實參的副本,它是直接對實參操作;而使用一般變量傳遞函數的參數,當發生函數調用時,需要給形參分配存儲單元,形參變量是實參變量的副本;如果傳遞的是對象,還將調用拷貝構造函數。因此,當參數傳遞的數據較大時,用引用比用一般變量傳遞參數的效率和所佔空間都好。

(3)使用指針作爲函數的參數雖然也能達到與使用引用的效果,但是,在被調函數中同樣要給形參分配存儲單元,且需要重複使用"*指針變量名"的形式進行運算,這很容易產生錯誤且程序的閱讀性較差;另一方面,在主調函數的調用點處,必須用變量的地址作爲實參。而引用更容易使用,更清晰。

 

結構與聯合有和區別

(1). 結構和聯合都是由多個不同的數據類型成員組成, 但在任何同一時刻, 聯合中只存放了一個被選中的成員(所有成員共用一塊地址空間), 而結構的所有成員都存在(不同成員的存放地址不同)。 

(2). 對於聯合的不同成員賦值, 將會對其它成員重寫, 原來成員的值就不存在了, 而對於結構的不同成員賦值是互不影響的。

 

19.請說出const與#define 相比,有何優點?

答案:

const作用:定義常量、修飾函數參數、修飾函數返回值三個作用。被Const修飾的東西都受到強制保護,可以預防意外的變動,能提高程序的健壯性。

1) const 常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查。而對後者只進行字符替換,沒有類型安全檢查,並且在字符替換可能會產生意料不到的錯誤。

2) 有些集成化的調試工具可以對const 常量進行調試,但是不能對宏常量進行調試。

 

基類的析構函數不是虛函數,會帶來什麼問題

這樣做是爲了當用一個基類的指針刪除一個派生類的對象時,派生類的析構函數會被調用。

當然,並不是要把所有類的析構函數都寫成虛函數。因爲當類裏面有虛函數的時候,編譯器會給類添加一個虛函數表,裏面來存放虛函數指針,這樣就會增加類的存儲空間。所以,只有當一個類被用來作爲基類的時候,才把析構函數寫成虛函數。

 

C和C++的區別?

c++在c的基礎上增添類,C是一個結構化語言,它的重點在於算法和數據結構。C程序的設計首要考慮的是如何通過一個過程,對輸入(或環境條件)進行運算處理得到輸出(或實現過程(事務)控制),而對於C++,首要考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題域,這樣就可以通過獲取對象的狀態信息得到輸出或實現過程(事務)控制。

 

設計模式懂嘛,簡單舉個例子?

答:設計模式(Designpattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。

比如單例模式,保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

適用於:當類只能有一個實例而且客戶可以從一個衆所周知的訪問點訪問它時;當這個唯一實例應該是通過子類化可擴展的,並且客戶應該無需更改代碼就能使用一個擴展的實例時。

比如工廠模式,定義一個用於創建對象的接口,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。

適用於:當一個類不知道它所必須創建的對象的類的時候;當一個類希望由它的子類來指定它所創建的對象的時候;當類將創建對象的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一信息局部化的時候。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章