c 7 拷貝建構函式和賦值建構函式

2021-07-08 20:51:56 字數 3590 閱讀 9935

參考:

int a = 100;

int b = a;

#include 

using

namespace

std;

class cexample

//拷貝建構函式

cexample(const cexample& c)

//一般函式

void show ()

cexample(const cexample& c) 就是我們自定義的拷貝建構函式。可見,拷貝建構函式是一種特殊的建構函式,函式的名稱必須和類名稱一致,它必須的乙個引數是本型別的乙個引用變數。

在c++中,下面三種物件需要呼叫拷貝建構函式!

class cexample 

(1).test物件傳入形參時,會先會產生乙個臨時變數,就叫 c 吧。

(2).然後呼叫拷貝建構函式把test的值給c。 整個這兩個步驟有點像:cexample c(test);

(3).等g_fun()執行完後, 析構掉 c 物件。

class cexample 

//拷貝構造

cexample(const cexample& c)

int main()

(1). 先會產生乙個臨時變數,就叫***x吧。

(2). 然後呼叫拷貝建構函式把temp的值給***x。整個這兩個步驟有點像:cexample ***x(temp);

(3). 在函式執行到最後先析構temp區域性變數。

(4). 等g_fun()執行完後再析構掉***x物件。

cexample a(100);

cexample b = a

; // cexample b(a);

rect::rect(const rect& r)

class

rect

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

static

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

private:

int width;

int height;

static

intcount; // 一靜態成員做為計數器

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

int main()

//改進後的**

class

rect

rect(const rect& r) // 拷貝建構函式

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

static

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

private:

int width;

int height;

static

intcount; // 一靜態成員做為計數器

};

class rect

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

}private:

int width;

int height;

int *p; // 一指標成員

};int main()

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

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

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

class rect

rect(const rect& r)

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

}private:

int width;

int height;

int *p; // 一指標成員

此時rect1的p和rect2的p各自指向一段記憶體空間,但它們指向的空間具有相同的內容,這就是所謂的「深拷貝」。

賦值建構函式是將乙個引數物件中私有成員賦給乙個已經在記憶體中佔據記憶體的物件的私有成員,賦值建構函式被賦值的物件必須已經在記憶體中,否則呼叫的將是拷貝建構函式,當然賦值建構函式也有深拷貝和淺拷貝的問題。

#include 

#include

using

namespace

std;

class a

a(const a& a) //拷貝建構函式的引數一定是引用,不能不是引用,不然會出現無限遞迴

a& operator=(const a& a) //記住形參和返回值一定要是引用型別,否則傳參和返回時會自動呼叫拷貝建構函式

n = new

int[10];

memcpy(n, a.n, 10);

cout

<

return *this;

}~a()

void get()

基類指標刪除派生類的物件

class clxbase

; virtual ~clxbase() {};

virtual

void dosomething() ;

};class clxderived : public clxbase

; ~clxderived() ;

void dosomething() ;

};

clxbase *ptest = new clxderived;

ptest->dosomething();

delete ptest;

do something in

class clxderived!

output from the destructor

ofclass

clxderived!

do something in

class

clxderived!

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

class cmystring 賦值建構函式 cmystring cmystring operator const cmystring str 新分配記憶體,將str的m pdata記憶體拷貝到m pdata中 m pdata new char strlen str.m pdata 1 strcpy...

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

拷貝構造是確確實實構造乙個新的物件,並給新物件的私有成員賦上引數物件的私有成員的值,新構造的物件和引數物件位址是不一樣的,所以如果該類中有乙個私有成員是指向堆中某一塊記憶體,如果僅僅對該私有成員進行淺拷貝,那麼會出現多個指標指向堆中同一塊記憶體,這是會出現問題,如果那塊記憶體被釋放了,就會出現其他指...

拷貝建構函式和賦值構造

為什麼空類可以建立物件呢?複製建構函式的引數可以是 const 引用,也可以是非 const 引用。一般使用前者,這樣既能以常量物件 初始化後值不能改變的物件 作為引數,也能以非常量物件作為引數去初始化其他物件。乙個類中寫兩個複製建構函式,乙個的引數是 const 引用,另乙個的引數是非 const...