建構函式 複製建構函式 型別轉換建構函式 析構函式

2021-07-04 03:56:28 字數 3836 閱讀 7853

成員函式的一種,名字與類名相同,可以有引數,不能有返回值(void也不行)。

乙個類可以有多個建構函式。

如果定義類時沒寫建構函式,則編譯器生成乙個預設的無參建構函式,這個建構函式不做任何操作。如果定義了建構函式,則編譯器不生成預設的無參建構函式。

物件生成時建構函式自動被呼叫,物件一旦生成,就再也不能在其上執行建構函式。物件占用的儲存空間不是建構函式分配的,建構函式是在物件已經占用的儲存空間上做一些初始化操作。只要物件生成,建構函式就會自動呼叫,不管這個物件是如何生成的。

例如:

class

complex;

complex::complex(double r,double i)

complex c1;//error,缺少建構函式的引數

complex *pc=new complex;//error,沒有引數

complex c1(2);

complex c1(2,4),c2(3,5);

complex *pc=new complex(3,4);

建構函式最好是public的,private建構函式不能直接用來初始化物件。例如,

class csample

};int main()

建構函式在陣列中的使用:

class csample;//陣列的兩個元素都呼叫有參建構函式

cout

<<"step2"

<2]=;//第乙個元素呼叫2建構函式,第二個呼叫1建構函式

cout

<<"step3"

delete array4;

return0;}

函式的輸出為:

constructor 1 called

constructor 1 called

step1

constructor 2 called

constructor 2 called

step2

constructor 2 called

constructor 1 called

step3

constructor 1 called

constructor 1 called

class

test //(1)

test

(int

n,int

m){}//(2)

test

(){} //(3)

};test array1[3]=;

//陣列有三個元素但是只給出了兩個初始值,因此三個元素分別用(1)

(2)(3)初始化

test array2[3]=;

//三個元素分別用(2)

(2)(1)初始化

test *parray[3]=;

//parray是指標陣列,不是物件陣列,它的三個元素都是指標分別指向某塊區域。如果只寫test *parray[3]而不寫等號後面的部分,則沒有物件生成,也不會引發test建構函式的呼叫。這裡只初始化了陣列的前兩個元素,因此只有兩個物件生成,new test

(4)的返回型別是test*,賦值給陣列的第乙個元素,也就是把新構造的物件的位址賦值給指標陣列的第乙個元素。這裡兩個元素分別呼叫(1)

(2)初始化。

只有乙個引數,即同類物件的引用,形如x::x(x&)或x::x(const x &),只能是物件的引用,不能是物件,不允許有形如x::x(x)的複製建構函式。

如果沒有定義複製建構函式,那麼編譯器生成預設複製建構函式,預設的複製建構函式完成複製功能。如果自己定義了複製建構函式,則預設的複製建構函式不存在。

複製建構函式起作用的三種情況:

1)當用乙個物件去初始化同類的另乙個物件時

complex c2(c1);

complex c2 = c1;//初始化語句,非賦值語句,呼叫複製建構函式

complex c1,c2;

c2 =c1;//賦值語句,不會呼叫複製建構函式,複製建構函式只有在初始化時才會呼叫

2)如果某函式的乙個引數是類a的物件,那麼該函式被呼叫時,類a的複製建構函式將被呼叫來初始化形參

class a;

a(a &a);

void func(a a1){}

int main()

程式輸出結果:copy

constructor

called

3)如果函式的返回值是類a的物件時,則函式返回時,a的複製建構函式被呼叫

class a

a(const a &a);

a func()

//返回值物件被初始化時呼叫複製建構函式,其引數是b,這裡返回值物件a的值是否等於b取決於複製建構函式怎麼寫

int main()

complex(double r,double i)

};int main()

輸出:intconstructor called

intconstructor called

9,0

名字與類名相同,在前面加『~』,沒有引數和返回值,乙個類最多只有乙個析構函式。

物件消亡時,析構函式自動被呼叫。

定義類時沒寫析構函式,則編譯器生成預設析構函式;定義了析構函式,則編譯器不生成預設析構函式。

析構函式不涉及釋放使用者申請的記憶體釋放等工作,如果使用者自己申請了記憶體空間,那麼使用者必須自己釋放,不然程式不會自動釋放使用者自己申請的記憶體空間。也就是說,程式裡面寫了new就必須有對應的delete,否則程式結束時不會自動析構使用者new的這塊空間。

析構函式和陣列:物件陣列生命期結束時,物件陣列的每個元素的析構函式都會被呼叫。

析構函式和運算子delete:delete運算導致析構函式呼叫。

ctest *ptest;

ptest = new ctest[3];//構造函式呼叫3次

delete ptest;//析構函式呼叫3次

class demo

func();

cout

<<"main ends"

0;}

輸出:

id=1 constructed

id=4 constructed

id=6 constructed

id=6 destructed

main

id=5 constructed

id=5 destructed

id=2 constructed

id=3 constructed

func

id=3 destructed

main ends

id=6 destructed

id=2 destructed

id=1 destructed

注: 1.d4=6是型別轉換,會生成臨時物件,因此有對臨時物件生成的建構函式和析構函式的呼叫。

2. 離物件最近的花括號是物件的作用域,作用域標誌著物件的生命週期,在物件的生命週期結束時要被析構。

3.func()函式內部定義了靜態變數d2和普通變數d3,它們的作用域是這個函式內部,但是靜態變數是在整個程式結束時析構,因此當func()結束時只析構變數d3。

4.d4是在main函式內部的區域性變數,所以main函式結束時d4析構,d1是全域性變數要在整個程式結束時析構,d2是靜態變數也要在整個程式結束時析構,先建立的後析構。

C 複製建構函式與型別轉換建構函式

複製構造引數只有乙個引數,即對同類物件的引用,形如 x x x 或x x const x 常用後者。若使用者未定義,則編輯器會生成預設的複製建構函式,完成複製的功能。class complex complex c1 呼叫預設無參建構函式 complex c2 c1 呼叫預設的複製建構函式,將 c2 ...

C 建構函式 析構函式 複製建構函式

無聊的廢話 距離開始放假已經過去半個月了,這半個月,品讀了一本實用型的繪畫書籍,作了幾幅作品,又做了乙個模型,只是探索未知領域總會遇到各種問題,甚至難以解決的問題,筆者頹廢了兩天煲了一部劇,覺得自己深深的辜負了時間,決定動手總結一下學過的知識,主要是總結資料結構,不過筆者看到當初c 的筆記,決定再鞏...

建構函式,複製建構函式和析構函式

這些函式在網上很容易就可以查到定義和寫法,這裡就不贅述了。令人感興趣的是這些函式什麼時候執行,特別是複製建構函式和析構函式。用編寫的一段 很醜的 來說明。include include include class point point const point obj point double ge...