1. 程式人生 > 其它 >[深度探索C++物件模型] 第一章 關於物件

[深度探索C++物件模型] 第一章 關於物件

1. 什麼是虛擬函式表?虛擬函式表的結構?

帶有虛擬函式的類物件或者存在虛擬繼承的類物件中,會有一個指向虛擬函式表的指標vptr,其指向一的一塊記憶體中儲存著當前類所對應的虛擬函式的地址。這塊記憶體是一張表格,即為虛擬函式表

下圖為類物件中虛擬函式表的示意圖

2. 虛擬繼承解決的問題?

虛擬繼承即virtual基類。若一個子類派生自多個父類,這些父類又同時派生自另一個相同的祖父類,那麼在例項化時,需要例項化多個父類的祖父類,會因為祖父類的內容相同而出現重名而無法例項化。而虛擬繼承可以保證,即使多個父類派生自同一個祖父類,在例項化時,也只有一個祖父類被例項化。這個也是鑽石結構問題。

3. 在虛擬繼承中,物件的結構是怎樣的?

在虛擬函式表的基礎上進行擴充,指向虛基類。(不準確,待更新)

4. 什麼是程式設計正規化?都有哪些常見的程式設計正規化?

程式設計正規化簡單來說就是指一種程式設計的思想和風格。主流的程式設計正規化有

結構化程式設計(面向過程),如C語言

面向物件程式設計,如C++,Java

函數語言程式設計,如Lisp

每種程式設計正規化都有自己的優缺點,現在各種主流語言已經開始支援各種程式設計正規化的融合

5. 多型是如何實現的?有繼承關係的物件如果直接賦值可能會導致什麼問題?

C++中的多型是通過指標和引用實現,具有虛擬函式或虛擬繼承關係的類可以實現多型。子類物件中的虛擬函式表在例項化時會與父類的虛擬函式表不同,因此在呼叫一個類物件的虛擬函式時可以實現多型。

有繼承關係的物件如果進行直接賦值可能會導致物件內容的切割,丟失部分內容(指子類物件)

6.抽象資料型別和麵向物件程式設計之間有什麼區別?

抽象資料型別(ADT)是將資料和對應的操作做成一個集合,而面向物件(OO)中則存在多種可能性,除了要將資料和方法進行封裝之外,還有多型。ADT中的資料和方法是單一實體,在編譯過程中就已經確定。

7. C++的語法中是如何支援多型的?

1)隱式指標轉換,如一個父類指標指向一個子類物件

2)virtual關鍵字,通過該關鍵字實現虛擬函式和虛基類,在執行時確定呼叫的方法

3)顯示指標轉換,用dynamic_cast將一個基類指標轉換為一個子類指標

8. 多型的主要用途是什麼?或者說是優點?

多型的主要用途是經由一組共同的介面來影響型別的封裝,也就是說,當類的內容(有新的繼承關係)發生變化時,程式碼無需進行改動

9. 一個類物件所佔用的記憶體可能由哪幾部分構成?

非靜態資料成員,虛擬函式表(及指標),資料對其引起的記憶體佔用

10. 指標是如何擁有不同型別的?比如int型指標和指向物件的指標之間是如何區別的?

依靠編譯器的解釋,在執行過程中,指標就是一個地址,不存在型別

11. 用一個子類物件去初始化一個基類物件時可能導致什麼問題?

當一個基類物件被初始化為一個子類物件時,子類物件會被切割以放入較小的基類物件所佔的記憶體中。此時,多型不會起作用

12. 基於物件(OB,Object Based)的程式設計有哪些優缺點?

OB,object-based,基於物件的。記憶體佈局更緊湊,因為不需要虛擬函式相關所佔用記憶體,執行也更快,因為不需要執行時利用虛擬函式表,函式呼叫在編譯時已確定。缺點是沒有靈活性。