深度探索C++對象模型之構造、解構、拷貝語意學小結

1、 一般而言,class的data members應該被初始化,並且只在constructor中或者是在class的member functions中指定初值。其他任何操作都將破壞封裝性,使class的維護和修改更加困難。

2、 可以定義並調用invoke一個pure virtual function,但它只能被靜態調用,不能經由虛擬機制調用。每一個derived class destructor會被編譯器加以擴展,靜態調用每一個virtual base class以及上一層base class的destructor。因此,不管base class的virtual destructor是否聲明爲pure,它必須被定義。最好的方案是不要把virtual destructor聲明爲pure。

3、 無繼承情況下的對象構造,C++ Standard要求編譯器儘量延遲nontrivial members的實際合成操作,直到真正遇到其使用場所爲止。

一般而言,繼承體系下編譯器對constructor所作的擴充操作以及次序大約如下:

(1) 所有virtual base class constructors必須從左到右、從深到淺被調用:如果class被列於member initialization list中,那麼任何明確指定的參數都必須傳遞過去,否則如果class有一個default constructor,也應該調用它; class中的每一個virtual base class subobject的偏移量offset必須在執行期可被存取;如果class object是最底層most-derived的class,其constructors可能被調用,某些用以支持這個行爲的機制必須被方進來。

(2) 以base class的聲明次序調用上一層base class constructors:如果base class被列於member initialization list中,那麼任何明確指定的參數都必須傳遞過去,否則若它有default constructor或default memberwise copy constructor,那麼就調用它;如果base class是多重繼承下的第二或後繼的base class,那麼this指針必須有所調整。

(3)  如果class object有virtual table pointer(s),它(們)必須被設定初值,指向適當的virtual table(s)。

4、對象複製語意學。只有在默認行爲所導致的語意不安全或者不正確以致發生別名化aliasing或者內存泄漏memory leak時,才需要設計一個copy assignment operator。否則,程序反倒會執行得較慢。如果僅僅是爲了把NRV優化開關打開而提供一個copy constructor,那麼就沒有必要一定要提供一個copy assignment operator。copy assignment operator有一個非正交情況,那就是它缺乏一個平行於member initialization list的member assignment list。

事實上,copy assignment operator在虛擬繼承情況下行爲不佳,需要小心設計和說明。許多編譯器甚至並不嘗試取得正確的語意,它們在每一箇中間的copy  assignment operator中調用每一個base class instance,於是造成virtual base copy assignment operator的多個實體被調用。建議儘可能不要允許一個virtual base class的拷貝操作,並不要在任何virtual base class中聲明data member。

5、 解構語意學。如果class沒有定義destructor,那麼只有在其內帶的member object或base class擁有destructor時,編譯器纔會自動合成出一個destructor。

一個由程序員定義的destructor被擴展的方式類似constructors被擴展的方式,只是順序相反:

 (1)destructor的函數本體首先被執行;

 (2)如果class擁有member class objects,而後者擁有destructors,那麼它們將以聲明的相反順序而調用;

 (3)如果object內帶一個vptr,則現在被重新設定以指向適當base class之virtual table;

 (4)如果有任何直接的nonvirtual base classes擁有destructor,它們將以聲明的相反順序而調用。

 (5)如果有任何virtual base classes擁有destructor,而前面討論的這個class是most-derived class,那麼它們會以原先構造順序的相反順序被調用。

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