建構函式 建構函式隱式轉換 拷貝建構函式

2021-08-14 22:21:42 字數 1749 閱讀 9927

建構函式對於我們來說是比較熟悉的,c++ primer裡提到:類通過乙個或幾個特殊的成員函式來控制其物件的初始化過程,為

建構函式

例1:

class fruit               //定義乙個類,名字叫fruit  

}

這樣的建構函式是我們比較常見的,但是如果變成

class fruit               //定義乙個類,名字叫fruit  

}

即使是乙個類中沒有任何的物件,我們仍然可以通過fruit fruit1;去建立乙個物件。

當我們的類中沒有任何的建構函式時,編譯器會自動建立乙個建構函式fruit(),這個稱為合成的預設建構函式。

class fruit               //定義乙個類,名字叫fruit  

private:

const string fname;

}

這裡拓展一下:類成員的初始化

fruit(const string &name):fname(name){}

fruit(const string &name):()

這兩種的初始化成員變數的區別:c++ primer中推薦第一種用法,建構函式是成員變數先初始化,然後再執行塊。如一種方式是先執行了fname(name),然後才把string fname變成const。而第二種方式初始化後再對fname=name進行賦值,則會提示不能給常量賦值的錯誤。

另外要講到的是建構函式的隱式轉換

轉換建構函式的定義:如果建構函式只接受乙個實參,則它實際上定義了轉換為此類型別的隱式轉換機制。

我們還是使用上面的例子,你會發現:

而第二種失敗的原因是由於編譯器char*轉換成fruit類需要進行兩步隱式轉換(fruit不能直接識別char*,所以需要char*->string->fruit),而編譯器只會自動地執行一步型別轉換。我們均能使用第一種方式或第三種方式。

但是不得不說,對於大型專案中,這種隱式操作對於我們的**是不穩定的,因為有時候會隱式轉換成我們不需要的,而我們卻很難發現,對於有乙個引數的建構函式,我們需要通過explicit進行限制,建構函式不允許隱式轉換。

拷貝建構函式

對於剛才的

也屬於拷貝初始化,拷貝建構函式與建構函式相同,如果類中沒有拷貝建構函式,系統會自動生成合成拷貝建構函式。

生成合成拷貝建構函式相當於

fruit(const fruit& f):fname(f.fname){}
拷貝初始化不僅在我們用=定義變數時發成,下列情況也會發生:

1.將乙個物件作為實參給乙個非引用引數型別的形參

2.從乙個返回型別為非引用型別的函式返回乙個形參

3.用花括號列表初始化乙個陣列中的元素活乙個聚合類中的成員(這種方式有興趣可以自己去了解一下)

void change(int &a,int b)

void main()

//執行結果c=1,d=4;

當使用引用時,c是直接操作之後返回的,可以理解成直接對其位址進行操作,而對於d作為實參到形參b時,會進行copy,不會直接操作d。故結果為c=1,d=4。

這個只是c中簡單的列子,在類中也是同樣的原理。

建構函式隱式轉換

建構函式會引起乙個不引人注意的問題 用單個實參來呼叫的建構函式定義了從從形參型別到類型別的乙個隱式轉換。舉個例子說 cpp view plain copy class sales item sales item add sales item other sales item const std st...

建構函式 拷貝建構函式 析構函式

1.如果定義了兩個預設建構函式,vc只回給出warning.2.如果有預設引數的預設構造,如果你給了第乙個預設的話 所有傳遞引數都要有預設植 否則報錯.不過如果是第乙個引數的預設值沒有給出的話,編譯器卻看不出問題,但是沒有 試過這種情況建構函式能不能正常工作.建構函式 用來初始化物件的資料成員,與類...

C 建構函式 拷貝構造 析構函式

建構函式 constructor 在例項物件時,系統自動呼叫,用來初始化物件的資料成員 建構函式宣告語法 類名 引數列表 建構函式注意點 include include using namespace std class computer 上面的建構函式也可以寫成引數列表初始化的形式 compute...