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

2021-07-04 08:32:17 字數 1675 閱讀 8717

#include using namespace std;

class string ;

建構函式、析構函式、賦值函式是每個類最基本的函式。每個類只有乙個析構函式和乙個賦值函式。但有很兩個建構函式,乙個為拷貝建構函式,其他為普通建構函式。

對於乙個類,如果不編寫這四個函式,c++編譯器將自動為a產生四個預設函式。那麼既然能自動生成函式,為什麼還要自定義?原因之一是預設的拷貝建構函式和預設的賦值函式都採用的是位拷貝而非值拷貝。

位拷貝拷貝的是位址,值拷貝拷貝的是內容。

在上面定義的string類裡,如果定義兩個string的物件a和b。當利用位拷貝時,a = b,其中a.val = b.val; 這個沒問題

但是a.m_data = b.m_data就錯了,a.m_data 和b.m_data作為指標將指向同乙個區域。這樣出現問題:

1. a.m_data 原來的記憶體區域未釋放,造成記憶體洩露

2. a.m_data和b.m_data指向同一塊區域,任何一方改變將會影響到另一方

3. 當物件釋放時,b.m_data會釋放兩次

因此當類中含有指標變數時,預設拷貝建構函式和預設賦值函式由於使用位拷貝就隱含了錯誤,這時需要自己定義。

結論1. 有一中特別常見的情況需要自己定義拷貝建構函式:類具有指標函式

2. 賦值操作符和拷貝建構函式可以看成乙個單元,當需要其中乙個時,我們幾乎也肯定需要另乙個

3. 三法則:如果類需要析構函式,則它也需要賦值操作符和拷貝建構函式

注意1. 如果沒有定義拷貝建構函式,編譯器會自動生成預設的拷貝建構函式

2. 如果定義了其他建構函式,包括拷貝建構函式,編譯器絕不會生成預設建構函式

3. 即使自己寫了析構函式,編譯器也會自動生成預設析構函式

/** copy.cpp

* * created on: 2015?8?5?

* author: nanzhou

*/#include using namespace std;

class string ;

string::string(const char *str)

else

}string::string(const string &other)

string & string::operator = (const string &other)

else

}string::~string()

int main() {

cout << "a(\"abc\")" << endl;

string a("abc");

cout << "b(\"cde\")" << endl;

string b("cde");

cout << " d = a " << endl;

string d = a;

cout << "c = a" << endl;

string c(b);

cout << " c = a " << endl;

c = a;

cout<2. 賦值函式裡,緊接著就要釋放m_data,否則就沒機會了,下邊就有新指向了

3. 拷貝建構函式是在物件被建立時呼叫,賦值函式只能被已經存在了的物件呼叫

string c = a;呼叫拷貝建構函式,因為c一開始不存在,最好攜程string c(a);

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

準備實現gof上面乙個迭代器模式,用到了上面的list基本類,但是一直對賦值函式和拷貝建構函式不是很熟悉,就研讀了一下effective c 的關於這方面的一章,頗有收穫,抽取了我認為精華的部分分享給大家。由於一直對c 這一類的用法不是很熟悉,有錯誤或者優化或者需要特別強調的地方希望朋友們幫忙指出來...

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

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

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

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