其實程式語言和我們所用的任何軟體沒有區別,例如photoshop、autocad之類。其唯一不同的是我們用的程式語言是基於編譯器的,而應用軟體是基於我們的程式語言的。
既然我們所用的軟體是基於編譯器的,那麼理解編譯器在背後到底為我們做了些什麼、在什麼情況下做了哪些事情就顯得異常重要。這就像photoshop會為你產生一些基本圖形例如矩形、三角形之類,而不會憑空產生一些風景優美的一樣。
在《c++ annotated reference manual(arm)[ellis90]》中的section 12.1告訴我們:"default constructors...在需要的時候被編譯器產生出來"。
其實預設建構函式也是分為兩類的:有用的、無用的。
所謂有用的標準也是就預設建構函式會為我們的類做一些初始化操作。那麼無用的就不會做任何工作,從而對我們的類也就沒有任何意義。所以,我們通常所說的預設建構函式是指有用的預設建構函式,其英文名字叫nontrivial default constructor。
那麼到底什麼時候編譯器會為我們產生nontrivial default constructor呢?有下面四中情況:
①如果乙個類裡面某個成員物件有nontrivial default constructor,編譯器就會為我們的類產生nontrivial default constructor。
那麼編譯器這樣做的理由是什麼?
答案是因為類成員物件有nontrivial default constructor,那麼編譯器就需要顯式的來呼叫這個類成員物件的nontrivial default constructor。而編譯器想顯式的呼叫類成員物件的nontrivial default constructor,就需要自己來合成一些**來呼叫。但是記住,編譯器合成的nontrivial default constructor僅僅呼叫類成員物件的預設建構函式,而不對我們類裡面的其它變數做任何初始化操作。
也就是說,如果你想初始化類成員變數以外的變數例如乙個int、乙個string,那麼必須自己定義預設建構函式來完成這些變數的初始化。而編譯器會對你定義的預設建構函式做相應的擴充套件,從而呼叫類成員物件的nontrivial default constructor。
②如果乙個派生類的基類有nontrivial default constructor,那麼編譯器會為派生類合成乙個nontrivial default constructor。
編譯器這樣的理由是:因為派生類被合成時需要顯式呼叫基類的預設建構函式。
③如何乙個類裡面隱式的含有任何virtual function table(或vtbl)、pointer member(或vptr)。
編譯器這樣做的理由很簡單:因為這些vtbl或vptr需要編譯器隱式(implicit)的合成出來,那麼編譯器就把合成動作放到了預設建構函式裡面。所以編譯器必須自己產生乙個預設建構函式來完成這些操作。
所以如果你的類裡帶有任何virtual function,那麼編譯器會為你合成乙個預設建構函式。
④如果乙個類虛繼承於其它類。
編譯器這樣做的理由和③類似:因為虛繼承需要維護乙個類似指標一樣,可以動態的決定記憶體位址的東西(不同編譯器對虛繼承的實現不僅相同)。
那麼除了以上四種情況,編譯器並不會為我們的類產生預設建構函式。
所以程式設計中切忌想當然,要明白哪些事情是編譯器做的,哪些事情需要程式設計師來完成的。就像堆所占用的資源需要程式設計師自己來釋放,而棧空間是編譯器管理的一樣。
只有如此,才能編寫出質量更高的**。
關於預設建構函式的幾個錯誤認識
其實程式語言和我們所用的任何軟體沒有區別,例如photoshop autocad之類。其唯一不同的是我們用的程式語言是基於編譯器的,而應用軟體是基於我們的程式語言的。既然我們所用的軟體是基於編譯器的,那麼理解編譯器在背後到底為我們做了些什麼 在什麼情況下做了哪些事情就顯得異常重要。這就像photos...
電路中「地」的錯誤認識
當訊號沿著傳輸線向前傳播時,訊號是以波的形式在移動,見下圖 看起來是不是像波浪向前推進,這個比喻非常好用,由於電訊號需要完整的電場線才能傳播,所以需要乙個返回路徑,圖中紅色為傳播路徑,黑色線為返回路徑,構成乙個完成的電場迴路,通常很多人會把黑色的部分稱作 地 這是乙個非常錯誤的認識,必須要加以改正。...
seo優化的一些錯誤認識
seo優化的一些錯誤認識 ai推聯盟 不優化是很難獲得排名的,但是 優化不好,同樣也很難獲得排名,人們在seo優化過程當中可能會對seo有一些錯誤的認識,下面就來分析一下。1 不要為了seo而seo 搜尋引擎不是公益組織,而是商業機構,本質也是追求利益。所以想讓搜尋引擎喜歡上我們,就需要先幫助搜尋引...