拷貝建構函式和賦值運算子區別 2010 01 03

2021-06-18 14:55:11 字數 3087 閱讀 9108

拷貝建構函式和賦值運算子區別

2010-01-03 11:30:03

分類: c/c++

『=』只有在賦值時,才呼叫賦值函式,當在宣告變數時,b b3=b1和b b4(b3)呼叫的函式是一樣的,均為拷貝建構函式。

一、拷貝構造,是乙個的物件來初始化一邊記憶體區域,這邊記憶體區域就是你的新物件的記憶體區域賦值運算,對於乙個已經被初始化的物件來進行operator=操作

class   a;    

a  a; 

a  b=a;   //拷貝構造函式呼叫 

//或 

a  b(a);   //拷貝構造函式呼叫 

///    

a  a; 

a  b; 

b =a;   //賦值運算子呼叫

你只需要記住,在c++語言裡, 

string   s2(s1); 

string   s3   =   s1; 

只是語法形式的不同,意義是一樣的,都是定義加初始化,都呼叫拷貝建構函式。

二、一般來說是在資料成員包含指標物件的時候,應付兩種不同的處理需求的 :

一種是複製指標物件,

一種是引用指標物件 copy大多數情況下是複製,=則是引用物件的    

即 深拷貝 和 淺拷貝

拷貝建構函式 是深拷貝

例子: 

class   a 

顯然 

a   a,   b; 

a=b的時候,對於pdata資料存在兩種需求 

第一種copy 

a.pdata   =   new   char   [nlen]; 

memcpy(a.pdata,   b.pdata,   nlen); 

另外一種(引用方式): 

a.pdata   =   b.pdata 

通過對比就可以看到,他們是不同的 

往往把第一種用copy使用,第二種用=實現

三、和拷貝建構函式的實現不一樣   

拷貝建構函式首先是乙個建構函式,它呼叫的時候產生乙個物件,是通過引數傳進來的那個物件來初始化,產生的物件。 

operator=();是把乙個物件賦值給乙個原有的物件,所以如果原來的物件中有記憶體分配要先把記憶體釋放掉,而且還要檢查一下兩個物件是不是同乙個物件,如果是的話就不做任何操作。

乙個例程

(自:)

以下討論中將用到的例子:

class cexample

~cexample()

void init(int n)

private:

char *pbuffer; //類的物件中包含指標,指向動態分配的記憶體資源

int nsize;};

這個類的主要特點是包含指向其他資源的指標。pbuffer指向堆中分配的一段記憶體空間。

一、拷貝建構函式

int main(int argc, char* argv)

語句"cexample theobjtwo=theobjone;" 是 淺拷貝

如果類中定義了拷貝建構函式,這物件建立時,呼叫的將是拷貝建構函式,在拷貝建構函式中,可以根據傳入的變數,複製指標所指向的資源。

拷貝建構函式的格式為:建構函式名(物件的引用)

提供了拷貝建構函式後的cexample類定義為:

class cexample

~cexample()

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

void init(int n)

private:

char *pbuffer; //類的物件中包含指標,指向動態分配的記憶體資源

int nsize;};

cexample::cexample(const cexample& rightsides) //拷貝建構函式的定義

1 定義新物件,並用已有物件初始化新物件時,cexample(const cexample& rightsides)將被呼叫,而已有物件用別名rightsides傳給建構函式,以用來作複製。

原則上,應該為所有包含動態分配成員的類都提供拷貝建構函式。

2  當物件直接作為引數傳給函式時,函式將建立物件的臨時拷貝,這個拷貝過程也將調同拷貝建構函式。

例如bool testfunc(cexample obj);

testfunc(theobjone); //物件直接作為引數。

bool testfunc(cexample obj)

3  還有一種情況,也是與臨時物件有關的

當函式中的區域性物件被被返回給函式調者時,也將建立此區域性物件的乙個臨時拷貝,拷貝建構函式也將被呼叫

ctest func()

二、賦值符的過載

下面的**與上例相似

int main(int argc, char* argv)

也用到了"="號,但與"一、"中的例子並不同,"一、"的例子中,"="在物件宣告語句中,表示初始化。更多時候,這種初始化也可用括號表示。

例如 cexample theobjone(theobjtwo);

而本例子中,"="表示賦值操作。將物件theobjone的內容複製到物件theobjthree;,這其中涉及到物件theobjthree原有內容的丟棄,新內容的複製。

但"="的預設操作只是將成員變數的值相應複製。舊的值被自然丟棄。

由於物件內包含指標,將造成不良後果:指標的值被丟棄了,但指標指向的內容並未釋放。指標的值被複製了,但指標所指內容並未複製。

因此,包含動態分配成員的類除提供拷貝建構函式外,還應該考慮過載"="賦值操作符號。

類定義變為:

class cexample;

//賦值操作符過載

cexample & cexample::operator = (const cexample& rightsides)

三、拷貝建構函式使用賦值運算子過載的**。

cexample::cexample(const cexample& rightsides)

拷貝建構函式和賦值運算子區別

只有在賦值時,才呼叫賦值函式,當在宣告變數時,b b3 b1和b b4 b3 呼叫的函式是一樣的,均為拷貝建構函式。一 拷貝構造,是乙個的物件來初始化一邊記憶體區域,這邊記憶體區域就是你的新物件的記憶體區域賦值運算,對於乙個已經被初始化的物件來進行operator 操作 class a a a a ...

拷貝建構函式和賦值運算子

把引數傳遞給函式有三種方法,一種是值傳遞,一種是傳位址,還有一種是傳引用。前者與後兩者不同的地方在於 當使用值傳遞的時候,會在函式裡面生成傳遞引數的乙個副本,這個副本的內容是按位從原始引數那裡複製過來的,兩者的內容是相同的。當原始引數是乙個類的物件時,它也會產生乙個物件的副本,不過在這裡要注意。一般...

拷貝建構函式和賦值運算子

來自 本文主要介紹了拷貝建構函式和賦值運算子的區別,以及在什麼時候呼叫拷貝建構函式 什麼情況下呼叫賦值運算子。最後,簡單的分析了下深拷貝和淺拷貝的問題。在預設情況下 使用者沒有定義,但是也沒有顯式的刪除 編譯器會自動的隱式生成乙個拷貝建構函式和賦值運算子。但使用者可以使用delete來指定不生成拷貝...