《effective C++》讀書筆記(三)

23.編譯器查找某個函數或變量的過程:

假設這個函數是某個派生類的成員函數

local作用域(函數內)->該派生類的作用域->該派生類基類的作用域->內含基類的namespace作用域->global作用域。

參考:《effective c++》p157

 

24.派生類內的名稱會遮掩基類的名稱(比如基類內有若干重載成員函數飛f(),派生類內又實現了自己的重載版本,那麼public繼承並不會讓基類的同名重載函數在派生類內可見——即被遮掩了)。在public繼承下從來沒人希望如此。因此,解決方法是:在派生類定義中在public部分使用using聲明——using Base::f。

參考:《effective c++》clause33

 

25.C++併發編程中,如果需要一個只讀常量對象,不妨將它定義爲一個靜態常量對象。因爲靜態對象可以允許多線程併發訪問,而且避免了構造和析構成本。

 

26. C++的頭文件(.h)和實現文件(.cpp)分別寫什麼

注:如果某個類只需要在自己的編譯單元內使用,可以將定義置於.cpp中

參考:

http://www.cnblogs.com/ider/archive/2011/06/30/what_is_in_cpp_header_and_implementation_file.html

 

27.

1)       聲明一個純虛函數的目的是爲了讓派生類只繼承函數接口。

2)       聲明一個普通的虛函數的目的是讓派生類繼承該接口和缺省實現(這個缺省實現是可選擇的)。風險在於派生類在未明白說出“我要”的情況下就繼承了該缺省行爲。

3)       普通成員函數(非虛)是讓派生類繼承接口和強制實現。

參考:《effectivec++》clause34

 

28.絕對不要重新定義繼承而來的非虛函數。

 

29.絕對不要重新定義一個繼承而來的虛成員函數缺省參數值(默認實參),因爲缺省參數值都是靜態綁定,而虛函數卻是動態綁定。即:不要給一個虛函數指定默認實參。因爲這會導致一種不一致性,而這種不一致性往往是錯誤的導火索。避免方法:採用替代虛函數的設計模式,比如NVI。

參考:《effective c++》clause37

 

30.類或對象的複合(composition)

複合(composition)意味着has-a(有一個)或is-implemented-in-terms-of(根據某物實現出)。對象可以分爲兩類:一類其實相當於你所塑造的時間中的某些事物,例如:人,汽車等等。這樣的對象屬於應用域。另一類對象則純粹是實現細節上的人工製品,像是緩衝區,互斥器,查找樹等等。這些對象相當於軟件的實現域。當複合發生於應用域之間,表現出has-a的關係;當它發生於實現域內則表現is-implemented-in-term-of的關係。

如何判斷是is-a(public繼承)還是is-implemented-in-terms-of?

public繼承要求如果D是一種B,那麼對B爲真的每一件事對D都爲真。

參考:《effective c++》clause38

 

31.private繼承

1)       如果classes之間的繼承關係是private,編譯器不會自動將一個派生類對象轉換爲一個基類對象,這與public繼承是不同的。

2)       private繼承意味着is-implemented-in-terms-of(根據某物實現出)。private繼承純粹只是一種實現技術。private繼承意味着只有實現部分被繼承,接口部分應略去。

 

32.隱式接口和編譯期多態

1)       類和模板都支持接口和多態。

2)       對類而言接口是顯示的,以函數簽名爲中心。多態則是通過virtual函數發生於運行期。

3)       對模板而言,接口是隱式的,奠基於有效表達式。多態則是通過模板具現化和函數函數重載解析發生在編譯器。

 

33.typename和class區別

1)       聲明template參數時,前綴關鍵字class和typename可互換。

2)       請使用關鍵字typename標識嵌套從屬類型名稱,但不得在定義繼承關係的基類列或成員初始化列表內以它作爲基類修飾符。

參考:《effective c++》clause42

 

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