Effective C++ 阅读笔记(一)透彻了解inline以及降低编译依存关系
inline內斂
1.類似于C中的#define
在C++中,提供了inline函數來代替C中的宏定義。(通常可以使用const來代替單純變量的宏定義,它可以提供類型檢查。對于形似函數的宏,最好改用inline函數來替換宏定義。)
編譯器最優化機制通常被設計用來濃縮那些“不含函數調用“的代碼,所以當你inline某個函數時,或許編譯器就因此有能力對它執行語境相關最優化。
2.效率問題
inline函數同#define宏定義一樣,都是以函數本體做替換,這樣做可能增加你的目標碼(object code),從而可能造成代碼膨脹(代碼膨脹會導致額外的換頁行為,降低指令高速緩存裝置的擊中率,帶來效率損失)。
如果inline函數本體很小,編譯器針對“函數本體”所產生的碼可能比針對“函數調用”所產生的碼可能更小。
3.是申請,而不是強制,也不一定要帶inline
注意,inline只是對編譯器的一個申請,不是強制命令。這項申請可以隱喻提出,也可以明確提出:
class person{ public:int age() const { return m_age; } //隱喻提出inline申請 private:int m_age; };4.虛函數可以inline嗎?
大部分編譯器都回拒絕太復雜的inline函數,而對所有的virtual虛函數都不能申請為inline函數,這是因為虛函數意味著”等待,直到運行期間才能確定調用哪個函數“,而inline意味著”執行前,先將調用動作替換為函數本體“。
5.構造函數和析構函數一般不應該是inline的
通常在繼承類中,即使是空的構造函數和析構函數,也會調用基類的構造函數和析構函數,如果是多重繼承的話代碼就會更加復雜。這樣如果再把它設為inline函數的話,出現的地方都回替換函數本體,那代碼量務必會增加的。
6.templates函數不一定要inline
templates通常放在頭文件中,編譯器將它具現化才能知道函數本體的內容。inline需要成本,所以要多加考慮,否則可能導致代碼膨脹。
7.程序升級與inline函數
inline函數無法隨程序庫的升級而升級,故需要升級的函數不要采用inline函數。
假如f是一個inline函數,這時如果把f編進程序中,一旦程序決定修改f函數,所有用到f的客戶端程序都必須重新編譯,這往往是不被接受的。如果是非Inline函數,一旦它有修改升級,程序只需要編譯這部分重新連接就好。
?
降低文件間的編譯依存關系
C++沒有把接口從實現中分離出來,為了實現接口與實現的分離,要使用聲明式,不要使用定義式。基于此構想的兩個手段是handle classes和interface classes。
int main() {int x;Person p(params); }當編譯器看到x的定義式,它知道必須分配多少內存才能夠容下一個int。但當編議器看到p的定義式,如何知道一個person有多大?唯一的辦法就是詢問class的定義式。然而如果class定義式不列出實現的細節,該怎么辦?
int main () {int x;Person *p; }只定義一個指向Person對象的指針。這里將不需要class的定義式,如果class Person的任何修改都不需要從新編譯這個函數文件。
也就是說,通過聲明的依賴性替代定義的依賴性,來實現接口與實現的分離。
?
所以需要注意:
如果使用object reference或object pointers能完成的任務,就不要使用object。references 和pointers只依靠類型聲明式,但object就要依靠類型的定義式了。
如果可以,盡量以class聲明式替換class定義式。
?
不知道從何時開始,在這里記筆記已經成為了一個習慣,不記下來總覺得就忘記了
?
?
?
?
總結
以上是生活随笔為你收集整理的Effective C++ 阅读笔记(一)透彻了解inline以及降低编译依存关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三国杀有趣的游戏id,三国杀游戏id取名
- 下一篇: 图书馆的标语文案29句