C (一) 建構函式與拷貝建構函式

2021-10-23 23:23:14 字數 1938 閱讀 1559

2. 拷貝建構函式

類通過乙個或幾個特殊的成員函式來控制其物件的初始化過程,這些函式叫做建構函式。建構函式的任務是初始化類物件的資料成員。

tip:建構函式不能宣告為const的。

形式1person ();//不帶任何引數,合成的預設建構函式就是該形式

//合成預設建構函式初始化規則:

1)如果存在類內的初始值,用它來初始化成員;(通常情況下不建議類內初始化,因為類內本質上是類的宣告,不分配記憶體,而初始化時要分配記憶體的)

2)否則,預設初始化該成員。

呼叫:person p1;//隱式呼叫形式1的預設建構函式

person p2=person();//顯式呼叫預設建構函式形式1

形式2:person(int age=18);//帶引數的預設建構函式;

呼叫:person p1;

//為什麼要有形式2?合成預設建構函式不香邁?

//因為:

1)若顯示定義了其他的建構函式,編譯器就不會給你預設合成了;

2)若定義在塊中的內建型別或復合型別(如陣列和指標)的物件被預設初始化(參考形式1初始化規則2)),則他們的值是未定義的。

3)當類中包含乙個其他類型別的成員且這個成員的類沒有預設建構函式,則編譯器無法初始化該成員,換句話說,不能為該類合成預設建構函式。

tip:該呼叫形式2並不會實際將p1的age賦初值為18,因為形式2的建構函式雖然傳遞引數了,但建構函式本身並未實現將該引數賦值給age。

解決:在函式體裡賦值或使用成員引數列表賦值。

形式2改進:person(int age=18):age(a);//建構函式初始值列表。

在引數列表對每乙個形參進行賦值,再用初始化成員列表方式用該值對成員變數初始化初始化。呼叫時直接完成對物件成員變數的初始化。

呼叫:person p1;//隱式呼叫預設建構函式形式2改進

tip:使用成員初始化列表,則引數必須有值(如18),若寫為person(int age):age(a){}形式,會報錯:找不到匹配的建構函式。

tip:當某個成員被建構函式初始值列表忽略時,它將以與合成預設建構函式相同的方式隱式初始化。

如果乙個建構函式第乙個引數是自身型別的引用(第乙個引數必須為引用,因為:若引數不是引用,則呼叫永遠不會成功——為了呼叫拷貝建構函式必須拷貝其實參,而為了拷貝其實參又必須呼叫拷貝建構函式,無限迴圈……),且任何額外引數都有預設值,則此建構函式是拷貝建構函式。

工作原理:一般情況,合成的拷貝建構函式將其引數的成員逐個拷貝到正在建立的物件中。

每個成員的型別據定了它如何拷貝:

1)類型別的成員,使用其拷貝建構函式來拷貝;

2)內建型別成員直接拷貝(合成拷貝建構函式對陣列是逐個拷貝乙個陣列型別的成員).

物件在幾種情況下會被拷貝:

1)使用=定義變數時;

2)以值的方式傳遞或返回乙個物件時;

3)用花括號列表初始化乙個陣列中的元素或乙個聚合類中的成員;

4)初始化標準庫容器或者呼叫insert或push成員時,容器會對其元素進行拷貝初始化,就要呼叫拷貝建構函式。

形式1:person(const person &){};

呼叫:person p2=p1;

形式2:person(const person &p):age(p.age){};

當類需要分配類物件之外的資源時(如管理動態記憶體的類、),合成的版本往往會失效(但包含vector或者string成員的類,合成版本可以正常工作,此時深拷貝的工作由vector、string、類保證)。

此時需要自定義拷貝建構函式進行深拷貝。

tip:即使我們定義了拷貝建構函式,編譯器也會為我們合成乙個拷貝建構函式。這一點注意與建構函式區分。

C 建構函式 拷貝建構函式

建構函式 class base private int m var 建構函式無返回值型別,函式名和型別相同。拷貝建構函式傳遞引數為引用。1 class base2 7 拷貝建構函式 8 base base ref m var ref m var 9 11 private 12 intm var 13...

拷貝建構函式與賦值建構函式

include stdafx.h include include using namespace std class a a a a 過載拷貝函式 a int id,char t name a char name a operator a a 注意 此處一定要返回物件的引用,否則返回後其值立即消失!...

拷貝建構函式與賦值建構函式

什麼時候用拷貝建構函式,和賦值建構函式 一 當用乙個已初始化過了的自定義類型別物件去初始化另乙個新構造的物件的時候,拷貝建構函式就會被自動呼叫。也就是說,當類的物件需要拷貝時,拷貝建構函式將會被呼叫。以下情況都會呼叫拷貝建構函式 乙個物件以值傳遞的方式傳入函式體 乙個物件以值傳遞的方式從函式返回 乙...