天天看點

深度探索C++ 對象模型【第一章2】

1:為了維護與C之間的相容性,C++保留了關鍵詞struct。那麼我們具體要在什麼時候來去對class和struct作出用法區分呢?

  • class和struct 的“一緻性”用法,隻是風格上的問題而已,C中的struct更偏向于資料封裝
  • 對于class,從C到C++,我們引入該關鍵詞,目的就是為了得到其所支援的封裝以及繼承特性
  • struct的本身帶有public接口,class本身帶有private接口
  • 保留它們的共存隻是為了C到C++的相容~

2:C++中,凡處于同一個access section的資料,必定保證其聲明順序與其在記憶體中的順序相一緻。但不同的access section中,排列順序就不一定了!~~。單一進制素數組問題:因為不同通路權限的塊中資料在記憶體中的位置不一定,單一進制素數組之後未必有足夠的記憶體,如果将private中單一進制素數組放在protected前面,那麼記憶體的連結配置設定可能就會出現問題(可能該數組記憶體的後面有資料存放)

3:C中的struct在C++中比較建議的用途:将資料封裝起來(無繼承的情況下),傳遞給C++所使用。

4:OO程式設計:object_oriented,隻有通過指針或是引用的間接處理,才能實作其多态的性質。相反,在ADT程式設計中,程式員處理的是一個擁有固定而單一類型的執行個體,其在編譯時已經完全确定好了。 個人了解:

  • 程式模型procedural:無類的概念
  • 抽象資料類型模型ADT:有類的出現,但是沒有多态
  • 面向對象模型OO:有類以及其多态特性的出現

5:多态相關

  • 多态定義:把具有繼承關系的多個類型稱為多态,因而我們可以使用這些類型而無需在意他們的差異。
  • 指針和引用的動态類型和靜态類型的不一緻性是C++支援多态的根本所在
  • 動态類型:變量或表達式在記憶體表達中的對象的類型(運作時才可确定)
  • 靜态類型:編譯時已知變量聲明的類型或表達式生成的類型

6:虛函數和非虛函數與多态的關系

  • 虛函數運作時才會決定執行的是哪個版本,判斷的依據是引用或指針所綁定的真實類型
  • 非虛函數的調用在編譯時期已經确定

7:public繼承中,可以直接的進行多态的轉換。而Nonpublic繼承(包括void*指針),必須由程式員通過顯式的轉換操作來通路。

8:C++支援的多态

  • 指針或引用的靜态動态類型不一緻
  • 虛函數機制
  • dynamic_cast和typeid運算符

9:多态的用途是經由一個共同的接口來影響類型的封裝,這個接口通常會被定義在一個抽象的base class中

10:class 對象的記憶體大小

  • nonstatic data members的大小總和
  • 虛函數所帶來的虛函數指針負擔
  • alignment(将數值調整到某數的倍數)帶來的補齊,32位機器上為4位元組的倍數

11:指針本身所需的記憶體大小是固定的,無論其指向哪一種資料類型,同樣的,引用在本質上也是以一個指針來實作的,是以其本身所需的記憶體也是固定的。!@但是!@,對于sizeof運算符來說,sizeof一個引用,傳回的是其引用對象的大小,sizeof一個指針,傳回的是其本身大小。

12:指針之間的不同之處在于:其尋址出來的object(對象)類型的不同,指針之間的記憶體、内容(一個機器位址)都是一樣的。

13:“類型”,這個詞就是為了解釋指針所跨越的位址長度的。是以對于void*類型的指針,我們無法知道其涵蓋的位址空間,它隻能持有一個位址,我們無法利用它操作其指向的object。

14“cast”,轉換這個詞,其實是一種編譯指令,大部分情況下它并不改變一個指針所含的真正位址,它隻影響“被指出記憶體的大小及其内容”的解釋方式。

15:當給一個基類的構造函數傳遞一個派生類對象時,基類的構造函數隻能夠初始化基類部分的成員,是以派生類的部分會被切掉~

bear b;
ZooAnimal *p = &b;
           

繼續閱讀