C C程式設計學習 梳理16 拷貝建構函式詳解

2021-09-12 08:19:41 字數 2138 閱讀 6281

原文:

目錄

一. 什麼是拷貝建構函式

二. 拷貝建構函式的呼叫時機

1. 物件以值傳遞的方式傳入函式引數

2. 物件以值傳遞的方式從函式返回

3. 物件需要通過另外乙個物件進行初始化;

三. 淺拷貝和深拷貝

1. 預設拷貝建構函式

2. 淺拷貝

3. 深拷貝

4. 防止預設拷貝發生

#include using namespace std;    

class cexample

//拷貝建構函式

cexample(const cexample& c)

//一般函式

void show ()

不能處理靜態變數:

class rect  

~rect() // 析構函式,計數器減1

static int getcount() // 返回計數器的值

private:

int width;

int height;

static int count; // 一靜態成員做為計數器

};

int rect::count = 0; // 初始化計數器

int main()

所謂淺拷貝,指的是在物件複製時,只對物件中的資料成員進行簡單的賦值,預設拷貝建構函式執行的也是淺拷貝。大多情況下「淺拷貝」已經能很好地工作了,但是一旦物件存在了動態成員,那麼淺拷貝就會出問題了,讓我們考慮如下一段**:

class rect  

~rect() // 析構函式,釋放動態分配的空間

} private:

int width;

int height;

int *p; // 一指標成員

};

int main()

在這段**執行結束之前,會出現乙個執行錯誤。原因就在於在進行物件複製時,對於動態分配的內容沒有進行正確的操作。我們來分析一下:

在執行定義rect1物件後,由於在建構函式中有乙個動態分配的語句,因此執行後的記憶體情況大致如下:

在使用rect1複製rect2時,由於執行的是淺拷貝,只是將成員的值進行賦值,這時 rect1.p= rect2.p,也即這兩個指標指向了堆裡的同乙個空間,如下圖所示: 

當然,這不是我們所期望的結果,在銷毀物件時,兩個物件的析構函式將對同乙個記憶體空間釋放兩次,這就是錯誤出現的原因。我們需要的不是兩個p有相同的值,而是兩個p指向的空間有相同的值,解決辦法就是使用「深拷貝」。

在「深拷貝」的情況下,對於物件中動態成員,就不能僅僅簡單地賦值了,而應該重新動態分配空間,如上面的例子就應該按照如下的方式進行處理:

rect(const rect& r)  

通過對物件複製的分析,我們發現物件的複製大多在進行「值傳遞」時發生,這裡有乙個小技巧可以防止按值傳遞——宣告乙個私有拷貝建構函式。甚至不必去定義這個拷貝建構函式,這樣因為拷貝建構函式是私有的,如果使用者試圖按值傳遞或函式返回該類物件,將得到乙個編譯錯誤,從而可以避免按值傳遞或返回物件。

class cexample   

private:

//拷貝構造,只是宣告

cexample(const cexample& c);

public:

~cexample()

void show ()

};

//全域性函式

void g_fun(cexample c)

int main()

C C程式設計學習 梳理10 函式的指標

原文 函式指標是指指向函式而非指向物件的指標。像其他指標一樣,函式指標也指向某個特定的型別 特定的函式型別 函式型別由其返回型別以及形參表確定,而與函式名無關。如下宣告了乙個函式指標 bool pfunc int,double 這個語句將pfunc宣告為指向函式的指標,它所指向的函式帶有兩個型別分別...

Reprint C 友元函式與拷貝建構函式詳解

一 友元函式 1.友元函式概述 1 友元函式是定義在乙個類外的普通函式。友元函式和普通函式的定義一樣 在類內必須將該普通函式宣告為友元。2 友元函式不是成員函式。不能通過物件來呼叫,而是直接呼叫 友元函式可以訪問類的公有 受保護以及私有成員,但是必須通過物件 物件指標或者物件引用來訪問。2.友元函式...

c c 拷貝控制 建構函式的問題

問題1 下面 處的 注釋掉後,就編譯不過,為什麼?問題2 但是把 處的也注釋掉後,編譯就過了,為什麼?編譯錯誤 001.cpp in copy constructor test test const test 001.cpp 21 22 error no matching function for ...