c++ 編譯期與運行期總結
一 見識編譯期的力量ios
#include "stdafx.h" #include <iostream> using namespace std; class A{ public: virtual void f(){ cout << "A" << endl; } }; class B :public A { private: void f(){ cout << "B" << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { A *pA = new B(); pA->f(); return 0; }
出現了頗有趣的結果,在main函數中,訪問到了B類中的私有方法。爲何會出現這樣的結果呢?c++
通常來講外部對象訪問類的私有成員,除非是友元,不然在編譯的時候就會報錯,可是上面那段代碼卻能夠正常的編譯經過。程序員
C++由於支持面向對象編程,制訂了一系列實現策略的語言機制。其中,各類各樣的「限制」主要是出如今編譯時:所以若是直接B d; d.f(); 就會致使編譯錯誤:編譯器發現 編程
B::f()是B類的私有成員函數,所以拒絕這樣的訪問。數組
這裏咱們能夠區分類和對象:類是編譯期的概念,也是「訪問權限」、「成員數據」、「成員函數」這幾個概念的「做用域」。而對象的做用域是運行期。它包括類的實例、引用和指針。 緩存
A *pA = new B(); 這裏 pA 是一個 A* , 因此就做爲一個A類的指針參與了編譯;安全
所以從pA調用f()在編譯器眼中,就是調用了A類的公開成員函數f()所以經過編譯;而後在運行時,因爲多態做用pA調用的f()是派生類的f()成員函數。app
雖然這時f()是private成員函數,可是因爲 private/public 這些訪問控制是編譯時的限制,在運行時無效,因此B::f() 被成功調用。jsp
若是可以理解這兩個在不一樣時間做用的概念,這個問題就很好理解.
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/lusure/archive/2009/12/31/5113217.aspx
2 上面的例子是轉載的,裏面有個例子是輸出調試信息的,
1)
const bool g_debug=1
void Log(char* str) {
if (g_debug){
printf(str);
}
}
2) #define DEBUG
#ifdef DEBUG
#define LOG(m) \
{\
printf(m);
\ }\
#else
#define LOG(m)
#endif
有經驗的程序員確定一眼就看出來第二種Log輸出方式比較好。第一種的判斷是在運行期,而第二種的判斷是在編譯期。第一種在每次運行log函數的時候都會去判斷全局變量,
而第二種是在編譯的時候就已經將不須要的Log信息定義爲空。由於編譯消耗的時間是一次性的,而運行的效率是直接呈現給用戶的。由這種節約時間的方法,
咱們能夠發現把不少函數的判斷和計算放在編譯期,會大大節約運行的時間,提供運行效率,可是編譯器並非萬能,因此編譯期能作的工做仍是十分的有限。
二 編譯期 運行期 說明
1. 編譯期是指把你的源程序交給編譯器編譯的過程,最終目的是獲得obj文件,連接後生成可執行文件。 運行期指的是你將可執行文件交給操做系統(輸入文件名,回車)執行、直到程序執行結束的期
執行的目的是爲了實現程序的功能 2. 編譯期分配內存,就是用靜態或全局數組。這是在編譯的時候肯定的。
編譯期內存錯誤,就是好比某個數據段DATA段或者CODE段等等,超過跑這個程序的目標機的存儲器的限制。好比DOS下,DATA段不能超過64K吧。
運行期分配內存,就是用malloc()之類的函數,在堆上分配內存。 運行期內存錯誤,就是運行的時候發生的,好比申請不到內存,內存越界訪問,等等。
除了內存外,編譯器還作了宏替換,檢查類型安全,上面一說的,類的「訪問權限」、「成員數據」、「成員函數」這幾個概念的「做用域」等等的語法檢查,其餘的我就不知道了。
三 編譯期執行的效率
例子: http://qiezi.javaeye.com/blog/60067 編譯期,把每一步操做結果的值都給緩存下來了,效率固然高了,咱們使用相同的緩存策略也能夠縮短函數的運行時間。
運行期執行的函數則沒有這個優勢,它和普通的函數沒有區別,不一樣點在於它在編譯的時候運行。把編譯器當作一種動態語言運行環境,那麼編譯「編譯期執行的函數」的過程就像是運行動態語言程序的過程。
若是程序中存在大量編譯期執行函數,可能極大地下降編譯效率,對於它的使用應該儘可能避免。
模板提供的是一種聲明式語法,在複雜的靜態執行邏輯面前有時候會顯得力不從心,編譯期執行函數在解決這個問題的同時,卻帶來了上面這種反作用。
若是能把二者的優勢結合起來用函數的語法來寫程序,由編譯器生成優化的模板代碼,這種編譯期執行才能夠大量使用。
一樣,能夠寫個梯乘的函數,求10000,在編譯器和運行期,各寫一個例子看看運行結果。就知道編譯期作運算的好壞。
四 模板的運用 1 stl 模板是在編譯期運行的,因此程序中儘可能用stl,除了安全性與規範性好外,stl的一些操做都在編譯時執行。
2 ATL ATL 跟com有個區別就是用了模板來取代com的虛擬表。ATL用了大量模板,不少操做都在編譯時執行了, 因此編出來的可執行文件,比較小。這個是我本身猜的。
3 泛型編程語言,C++強大(但容易失控的)模板功能使它能在編譯期完成許多工做,從而大大提升運行期效率。這個東西比較難,暫時沒詳細瞭解。一個不錯 的例子:
http://wgysh1987.blog.163.com/blog/static/67986941200952454710401/