14.1
類的初始化
型如下面這樣的類:
class data
;可用如下方式初始化,而不需要提供建構函式:
data local1 = ; //
稱為顯式初始化表
這是因為其資料成員都是公有的。
對於大多數類而言,提供乙個建構函式初始化資料成員是乙個好的選擇。但是上面的初始化形式在
初始化大型資料結構,如調色盤類
時尤其有用,可節省構造函式呼叫開銷。
14.2
類的建構函式
建構函式與類同名,不可指定返回型別。
建構函式可以有多個,但參數列必須唯一。
使用new
時,只有當成功得到了記憶體,編譯器才會呼叫類建構函式。
只有當沒有建構函式或者定義了預設建構函式時,我們才可以不指定實參集來定義類物件。
在實踐中,如果定義了其他建構函式,則建議提供乙個預設建構函式。
建構函式不能是
const
或者是volatile
。在預設情況下,單引數建構函式被用作轉換操作符。使用關鍵字
explicit
可以抑制無意的隱士轉換。
例:extern void print(account& acct);
…int main()
14.2.1
預設建構函式
預設建構函式是指不需要使用者指定實參就能夠被呼叫的建構函式。這並不意味著它不能接受實參,如:
istack::istack(int isize = 0)
是乙個預設建構函式。
如果類資料成員都是公有的,並且沒有使用者定義的建構函式,則類物件的成員初始化值取決於上下文環境。如果為靜態物件,則可保證成員初始值為
0.如為區域性定義或者是動態分配的物件,則初始值為隨機。
如果不存在預設建構函式,編譯器不一定會生成乙個。(在
<
深度探索
c++物件模型
>
一書中提到,在以下四種情況下編譯器將提供乙個為乙個類提供預設建構函式:
1.其基類有預設建構函式;
2.其物件成員有預設建構函式;
3.其擁有虛函式;
4.其擁有虛基類
)14.2.2
限制物件建立
將建構函式非公有化。這樣做的好處是:
防止將乙個類的物件向該類另乙個物件拷貝;
指出只有當該類作為基類,而不能被應用程式直接呼叫時,建構函式才能被呼叫。
14.2.3
拷貝建構函式
將相同類的不同物件相互賦值,預設方式是按成員初始化。當存在指標成員時,顯然不合適,此時需要提供拷貝建構函式。
拷貝建構函式擁有乙個指向類物件的引用作為引數。
14.3
類的析購函式
析構函式是乙個特殊的由使用者提供的函式,當該類的物件離開了它的作用域,或者
delete
操作應用到該類的物件指標時,會被自動呼叫。
當乙個類的資料成員按值儲存時,不需要析構函式,(如:
float x, y, z).
c++語言內部保證,不會
delete
乙個不指向任何物件的指標。
14.3.1
顯示的析構呼叫
14.4
類物件陣列
型如這樣定義:
account table[3] =
14.5
成員初始化表
不存在從
string
類到char*
的隱式轉換,但
string
類支援從
char*
轉換到string
。通過成員初始化表,類資料成員可以被顯式初始化。
建構函式的執行被分為兩個階段:隱式或者顯式初始化階段;計算執行階段,由建構函式體內所有語句構成。
不存在成員初始化列表時,初始化是隱式的,基類以及所有成員類物件的預設建構函式將被呼叫。
除了const
和引用資料成員之外
(這兩種只能使用成員初始化表
),使用初始化列表和使用賦值語句的結果和效能是等價的。
初始化順序與類成員物件被宣告的順序相對應,而與初始化列表順序無關。
初始化列表中的成員的初始化總是先於建構函式體內被賦值的成員。為了避免錯誤,通常建議將乙個成員初始化另乙個成員的賦值動作放在建構函式體內。
14.6
按成員初始化
用乙個類物件初始化另乙個類物件,如:
1.用乙個類物件顯式初始化另乙個類物件
: account newaccount(oldaccount);
2.將乙個類物件作為實參傳遞給乙個函式:
extern a(account account); if (a(oldaccount)
3.將乙個類物件作為乙個函式的返回值傳遞回來。
4.非空順序容器的定義
預設的是按成員初始化,無論是否存在顯式建構函式。
此時容易發生指標「別名」問題。可以通過提供乙個顯示拷貝建構函式解決。另外也可以通過以下替代方案,禁止按成員初始化:
1.宣告乙個
private
的拷貝建構函式,這樣可以防止按成員初始化出現在
除成員函式和友元函式以外的
其它任何地方;
2.不提供該函式的定義。編譯通過但產生連線錯誤。
14.6.1
成員類物件的初始化
如果乙個類提供了乙個顯式拷貝建構函式,則呼叫該函式進行初始化,否則預設按成員初始化
14.7
按成員賦值
類似於按成員初始化。
14.8
效率問題
nlv優化,見
深度探索
c++物件模型。
所以,盡量使用如下語句:
matrix c = a + b;
而不是:
matrix c;
c = a + b;
初始化 賦值 拷貝
折騰我挺長一段時間,基本挺明白了,先來個區別說明 賦值操作是在兩個已經存在的物件間進行的,而初始化是要建立乙個新的物件,並且其初值 於另乙個已存在的物件。編譯器會區別這兩種情況,賦值的時候呼叫過載的賦值運算子,初始化的時候呼叫拷貝建構函式。如果類中沒有拷貝建構函式,則編譯器會提供乙個預設的。這個預設...
賦值與初始化
1 賦值 賦值 是給變數指定乙個值或者是改變乙個變數的值,且 必須是在該變數型別所能表達的範圍之內。int speed 30 標準形式 variable expression 變數型別 變數名 表示式 2 初始化 區域性變數 必須顯示的進行初始化。例項變數 類變數 編譯器可以自動對它們進行初始化。b...
成員初始化列表 初始化同賦值的區別
成員初始化列表 初始化同賦值的區別 1.我們可以認為建構函式的執行過程被分成兩個階段,隱式或顯式初始化階段以及一般的計算階段。計算階段由建構函式體內的所有語句構成,在計算階段中資料成員的設定被認為是賦值而不是初始化。初始化階段可以是顯式的或隱式的,取決於是否存在成員初始化表。隱式初始化階段按照宣告的...