c 拷貝函式

2021-09-24 11:19:47 字數 2827 閱讀 5276

2019.6.14 c++拷貝建構函式詳解

一、什麼是拷貝建構函式

首先對於普通型別的物件來說,他們之間的複製是很簡單的,例如:

int a = 100;

int b = a;

而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。

下面看乙個類物件拷貝的簡單例子。

#includeusing namespace std;

class cexample

//拷貝建構函式

cexample(const cexample & c)

//析構函式

~cexample()

void show()

cexample(const cexample & c)

~cexample()

void show()

//拷貝建構函式

cexample(const cexample & c)

//析構函式

~cexample()

void show()

#includeusing namespace std;

class rect

~rect()

static int getcount()

private:

int width;

int height;

static int count;

};int rect::count=0;

int main()

rect(const rect& r)

~rect()

static int getcount()

private:

int width;

int height;

static int count;

};int rect::count=0;

int main()

, 如果呼叫foo(obj);  首先class_type obj_local(obj) ,這樣就定義了區域性變數obj_local供函式內部使用

ii)引用傳遞:

無論對內建型別還是類型別,傳遞引用或指標最終都是傳遞的位址值!而位址總是指標型別(屬於簡單型別), 顯然引數傳遞時,按簡單型別的賦值拷貝,而不會有拷貝建構函式的呼叫(對於類型別).

4. 在類中有指標資料成員時,拷貝建構函式的使用?

如果不顯式宣告拷貝建構函式的時候,編譯器也會生成乙個預設的拷貝建構函式,而且在一般的情況下執行的也很好。但是在遇到類有指標資料成員時就出現問題 了:因為預設的拷貝建構函式是按成員拷貝構造,這導致了兩個不同的指標(如ptr1=ptr2)指向了相同的記憶體。當乙個例項銷毀時,呼叫析構函式 free(ptr1)釋放了這段記憶體,那麼剩下的乙個例項的指標ptr2就無效了,在被銷毀的時候free(ptr2)就會出現錯誤了, 這相當於重複釋放一塊記憶體兩次。這種情況必須顯式宣告並實現自己的拷貝建構函式,來為新的例項的指標分配新的記憶體。

問題1和2回答了為什麼拷貝建構函式使用值傳遞會產生無限遞迴呼叫的問題;

問題3回答了回答了在類中有指標資料成員時,拷貝建構函式使用值傳遞等於白顯式定義了拷貝建構函式,因為預設的拷貝建構函式就是這麼幹的。

5. 拷貝建構函式裡能呼叫private成員變數嗎?

解答:這個問題是在網上見的,當時一下子有點暈。其時從名子我們就知道拷貝建構函式其時就是乙個特殊的建構函式,操作的還是自己類的成員變數,所以不受private的限制。

6. 以下函式哪個是拷貝建構函式,為什麼?

x::x(const x&); //拷貝建構函式

x::x(x);

x::x(x&, int a = 1); //拷貝建構函式

x::x(x&, int a = 1, int b = 2); //拷貝建構函式

解答:對於乙個類x, 如果乙個建構函式的第乙個引數是下列之一:

a) x&

b) const x&

c) volatile x&

d) const volatile x&

且沒有其他引數或其他引數都有預設值,那麼這個函式是拷貝建構函式.

7. 乙個類中可以存在多於乙個的拷貝建構函式嗎?

解答:類中可以存在超過乙個拷貝建構函式。

class x
注意,如果乙個類中只存在乙個引數為 x& 的拷貝建構函式,那麼就不能使用const x或volatile x的物件實行拷貝初始化.

如果乙個類中沒有定義拷貝建構函式,那麼編譯器會自動產生乙個預設的拷貝建構函式。

這個預設的引數可能為 x::x(const x&)或 x::x(x&),由編譯器根據上下文決定選擇哪乙個。

五、c++建構函式以及析構函式的若干面試問題

q1:建構函式能否過載,析構函式能否過載,為什麼?

a1:建構函式可以,析構函式不可以。

q2:析構函式為什麼一般情況下要宣告為虛函式?

a2:虛函式是實現多型的基礎,當我們通過基類的指標是析構子類物件時候,如果不定義成虛函式,那只呼叫基類的析構函式,子類的析構函式將不會被呼叫。如       果定義為虛函式,則子類父類的析構函式都會被呼叫。

q3:什麼情況下必須定義拷貝建構函式?

a3:當類的物件用於函式值傳遞時(值引數,返回類物件),拷貝建構函式會被呼叫。如果物件複製並非簡單的值拷貝,那就必須定義拷貝建構函式。例如大的堆       棧資料拷貝。如果定義了拷貝建構函式,那也必須過載賦值操作符。

參考部落格:

C 拷貝建構函式 深拷貝,淺拷貝

對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。執行程式,螢幕輸出100。從以上 的執行結果可以看出,系統為物件b分配了記憶體並完成了與物件a的複製過程。就...

C 拷貝建構函式 深拷貝,淺拷貝

對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。include using namespace std class cexample void show 執...

C 拷貝建構函式 深拷貝,淺拷貝

c 拷貝建構函式 深拷貝,淺拷貝 對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。iostream using namespace std class ce...