與任何其他函式一樣,建構函式具有名字、形參表和函式體。與其他函式不同的是,建構函式也可以包含乙個建構函式初始化列表。
a)sales_item::sales_item(const string &book): isbn(book), units_sold(0), revenue(0.0)
b)sales_item::sales_item(const string &book)
合理的使用建構函式的初始化式是非常重要的,b)類 sales_item 的成員賦值,但沒有進行顯式初始化。不管是否有顯式的初始化式,在執行建構函式之前,要初始化isbn 成員。這個建構函式隱式使用預設的 string 建構函式來初始化 isbn。執行建構函式的函式體時,isbn 成員已經有值了。該值被建構函式函式體中的賦值所覆蓋。
從概念上講
,可以認為建構函式分兩個階段執行:(1)初始化階段;(2)普通的計算階段。計算階段由建構函式函式體中的所有語句組成。
不管成員是否在建構函式初始化列表中顯式初始化,
類型別的資料成員總是在初始化階段初始化。初始化發生在計算階段開始之前。兩個版本具有同樣的效果:無論是在建構函式初始化列表中初始化成員,還是在建構函式函式體中對它們賦值,最終結果是相同的。建構函式執行結束後,三個資料成員儲存同樣的值。
不同之外在於,使用建構函式初始化列表的版本初始化資料成員,沒有定義初始化列表的建構函式版本在建構函式函式體中對資料成員賦值。這個區別的重要性取決於資料成員的型別。
有些成員必須在建構函式初始化列表中進行初始化。對於這樣的成員,在建構函式函式體中對它們賦值不起作用。
沒有預設建構函式的類型別的成員,以及 const 或引用型別的成員,不管是哪種型別,都必須在建構函式初始化列表中進行初始化。
因為內建型別的成員不進行隱式初始化,所以對這些成員是進行初始化還是賦值似乎都無關緊要。除了兩個例外(const 和引用),對非類型別的資料成員進行賦值或使用初始化式在結果和效能上都是等價的。
例如,下面的建構函式是錯誤的:
class constref ;
// no explicit constructor initializer: error ri is uninitialized
constref::constref(int ii)
// ok: explicitly initialize reference and const members
constref::constref(int ii): i(ii), ci(i), ri(ii)
在許多類中,初始化和賦值嚴格來講都是低效率的:資料成員可能已經被直接初始化了,還要對它進行初始化和賦值。比較率問題更重要的是,某些資料成員必須要初始化,這是乙個事實。
C 中靜態建構函式的幾點注意
靜態建構函式是c 的乙個新特性,其實好像很少用到。不過當我們想初始化一些靜態變數的時候就需要用到它了。這個建構函式是屬於類的,而不是屬於 例項的,就是說這個建構函式只會被執行一次。也就是在建立第乙個例項或引用任何靜態成員之前,由.net自動呼叫。class class static construc...
關於C 靜態建構函式的幾點說明
靜態建構函式是c 的乙個新特性,其實好像很少用到。不過當我們想初始化一些靜態變數的時候就需要用到它了。這個建構函式是屬於類的,而不是屬於 例項的,就是說這個建構函式只會被執行一次。也就是在建立第乙個例項或引用任何靜態成員之前,由.net自動呼叫。class class 在使用靜態建構函式的時候應該注...
關於C 靜態建構函式的幾點說明
靜態建構函式是c 的乙個新特性,其實好像很少用到。不過當我們想初始化一些靜態變數的時候就需要用到它了。這個建構函式是屬於類的,而不是屬於 例項的,就是說這個建構函式只會被執行一次 也就是在建立第乙個 例項或引用任何靜態成員之前,由.net自動呼叫。class class 在使用靜態建構函式的時候應該...