C++細節問題

1:引用和指針有什麼區別?

參考答案
本質:引用是別名,指針是地址,具體的:
• 指針可以在運行時改變其所指向的值,引用一旦和某個對象綁定就不再改變
• 從內存上看,指針會分配內存區域,而引用不會,它僅僅是一個別名
• 在參數傳遞時,引⽤用會做類型檢查,而指針不會
• 引用不能爲空,指針可以爲空

2:const和define有什麼區別?

參考答案
本質:define只是字符串替換,const參與編譯運行,具體的:
• define不會做類型檢查,const擁有類型,會執行相應的類型檢查
• define僅僅是宏替換,不佔⽤用內存,⽽而const會佔用內存
• const內存效率更高,編譯器通常將const變量保存在符號表中,而不會分配存儲空間,這使得它成 爲一個編譯期間的常量,沒有存儲和讀取的操作

3:define和inline有什麼區別?

參考答案
本質:define只是字符串替換,inline由編譯器控制,具體的:
• define只是簡單的宏替換,通常會產生二義性;而inline會真正地編譯到代碼中
• inline函數是否展開由編譯器決定,有時候當函數太大時,編譯器可能選擇不展開相應的函數

4:malloc和new有什麼區別?

參考答案
1,malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用於申請動態內存和釋放內存。
2,對於非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。
3,因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。
4,C++程序經常要調用C函數,而C程序只能用malloc/free管理動態內存。
5、new可以認爲是malloc加構造函數的執行。new出來的指針是直接帶類型信息的。而malloc返回的都是void指針。

5:C++中static關鍵字作用有哪些

參考答案
1、隱藏:當同時編譯多個文件時,所有未加static前綴的全局變量和函數都具有全局可見性。
static可以用作函數和變量的前綴,對於函數來講,static的作用僅限於隱藏.
2、static的第二個作用是保持變量內容的持久:存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是唯一的一次初始化。
共有兩種變量存儲在靜態存儲區:全局變量和static變量,只不過和全局變量比起來,static可以控制變量的可見範圍,
說到底static還是用來隱藏的。雖然這種用法不常見
3、static的第三個作用是默認初始化爲0(static變量)
4、C++中的作用
1)不能將靜態成員函數定義爲虛函數。
2)靜態數據成員是靜態存儲的,所以必須對它進行初始化。 (程序員手動初始化,否則編譯時一般不會報錯,但是在Link時會報錯誤)
3)靜態數據成員在<定義或說明>時前面加關鍵字static。

補充:請說出static和const關鍵字儘可能多的作用

【解答】

static關鍵字至少有下列n個作用:

(1)函數體內static變量的作用範圍爲該函數體,不同於auto變量,該變量的內存只被分配一次,因此其值在下次調用時仍維持上次的值;

(2)在模塊內的static全局變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問;

(3)在模塊內的static函數只可被這一模塊內的其它函數調用,這個函數的使用範圍被限制在聲明它的模塊內;

(4)在類中的static成員變量屬於整個類所擁有,對類的所有對象只有一份拷貝;

(5)在類中的static成員函數屬於整個類所擁有,這個函數不接收this指針,因而只能訪問類的static成員變量。

const關鍵字至少有下列n個作用:

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

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

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

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

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

const classA operator*(const classA& a1,const classA& a2);
operator*的返回結果必須是一個const對象。如果不是,這樣的變態代碼也不會編譯出錯:

classA a, b, c;
(a * b) = c; // 對a*b的結果賦值
操作(a * b) = c顯然不符合編程者的初衷,也沒有任何意義。

6:C++中包含哪幾種強制類型轉換?他們有什麼區別和聯繫?

參考答案
• reinterpret_cast: 轉換一個指針爲其它類型的指針。它也允許從一個指針轉換爲整數類型,反之亦 然. 這個操作符能夠在非相關的類型之間轉換. 操作結果只是簡單的從一個指針到別的指針的值的 二進制拷貝. 在類型之間指向的內容不做任何類型的檢查和轉換?
class A{};
class B{};
A* a = new A;
B* b = reinterpret_cast(a);
• static_cast: 允許執行任意的隱式轉換和相反轉換動作(即使它是不允許隱式的),例如:應用到類 的指針上, 意思是說它允許子類類型的指針轉換爲父類類型的指針(這是一個有效的隱式轉換), 同 時, 也能夠執行相反動作: 轉換父類爲它的子類
class Base {};
class Derive:public Base{};
Base* a = new Base;
Derive *b = static_cast(a);
• dynamic_cast: 只用於對象的指針和引用. 當用於多態類型時,它允許任意的隱式類型轉換以及相 反過程. 不過,與static_cast不同,在後一種情況裏(注:即隱式轉換的相反過程),dynamic_cast 會檢查操作是否有效. 也就是說, 它會檢查轉換是否會返回一個被請求的有效的完整對象。檢測在 運行時進行. 如果被轉換的指針不是一個被請求的有效完整的對象指針,返回值爲NULL. 對於引用 類型,會拋出bad_cast異常
• const_cast: 這個轉換類型操縱傳遞對象的const屬性,或者是設置或者是移除,例如:
class C{};
const C* a = new C;
C *b = const_cast(a);

7:簡述C++虛函數作用及底層實現原理

參考答案
要點是要答出虛函數表和虛函數表指針的作用。C++中虛函數使用虛函數表和 虛函數表指針實現,虛函數表是一個類的虛函數的地址表,用於索引類本身以及父類的虛函數的地 址,假如子類的虛函數重寫了父類的虛函數,則對應在虛函數表中會把對應的虛函數替換爲子類的 虛函數的地址;虛函數表指針存在於每個對象中(通常出於效率考慮,會放在對象的開始地址處), 它指向對象所在類的虛函數表的地址;在多繼承環境下,會存在多個虛函數表指針,分別指向對應 不同基類的虛函數表。

8:構造函數中可以調用虛函數嗎?

參考答案
可以,但是沒有動態綁定的效果,父類構造函數中調用的仍然是父類版本的函數,子類中調用的仍然是子類版本的函數

9:簡述C++中虛繼承的作用及底層實現原理?

參考答案
虛繼承用於解決多繼承條件下的菱形繼承問題,底層實現原理與編譯器相關,一般通過虛基類 指針實現,即各對象中只保存一份父類的對象,多繼承時通過虛基類指針引用該公共對象,從而避 免菱形繼承中的二義性問題。

參考網站:
http://www.nowcoder.com/ta/nine-chapter/review?page=69

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