C 中的淺拷貝與深拷貝

2021-08-03 13:01:49 字數 1865 閱讀 3015

用自定義的string類解釋什麼是淺拷貝什麼是深拷貝。

class string 

;

淺拷貝是在呼叫拷貝函式時進行了值拷貝,這樣的拷貝看似沒有問題,在呼叫析構函式時會導致記憶體洩漏,系統奔潰。

#define _crt_secure_no_warnings 1

#includeusing namespace std;

class string

~string() }

char *getstr()

private:

char*_str;

};void teststring()

int main()

我們自己編寫了建構函式和析構函式,在執行測試用例時出現系統奔潰:

是因為在string s3(s1)時系統呼叫預設拷貝構造即「淺拷貝」。

所以我們要自己編寫拷貝構造與賦值運算子過載,進行深拷貝。

深拷貝是指在拷貝構造時,新開闢一塊空間,將_str指向的內容拷貝到這塊新的空間裡,再將自己的_str指向這塊空間。下面是**:

#define _crt_secure_no_warnings 1

#includeusing namespace std;

class string

~string() }

string(const string& d)

string& operator=(const string& d)

return *this;

} char *getstr()

private:

char*_str;

};void teststring()

執行結果為:

深拷貝有兩種寫法,第一種是傳統寫法,就是我上面這種寫法,老老實實開闢新空間,老老實實拷貝字串;

還有一種是現**法,相對於傳統寫法更簡潔一點,是讓別人開空間拷貝字串,再將別人的空間與自己交換,坐享漁翁之利。

**如下:

#define _crt_secure_no_warnings 1

#includeusing namespace std;

class string

~string() }

string(const string& d)

:_str(null) //如果tmp置空可以避免釋放野指標

string& operator=(const string& d)

return *this;

} char *getstr()

private:

char*_str;

};void teststring()

int main()

現**法中的賦值運算子過載也可以使用物件引數,上面使用的是引用。

string& operator=(string s)

在這種寫法中,因為引數是乙個臨時變數,所以在呼叫賦值函式時string s就是物件的臨時拷貝,可以直接交換,

string s因為是臨時變數,在出了作用域後自動銷毀,不用自己呼叫delete函式。

c 中深拷貝與淺拷貝

如果沒有自定義複製建構函式,則系統會建立預設的複製建構函式,但系統建立的預設複製建構函式只會執行 淺拷貝 即將被拷貝物件的資料成員的值一一賦值給新建立的物件,若該類的資料成員中有指標成員,則會使得新的物件的指標所指向的位址與被拷貝物件的指標所指向的位址相同,delete該指標時則會導致兩次重複del...

C 中的深拷貝與淺拷貝

1 拷貝建構函式 定義 如果乙個類的建構函式的第乙個引數是類自身類型別的引用,且任何額外引數都有預設值,則此建構函式為拷貝建構函式。由此可見,拷貝建構函式是一種特殊的建構函式,乙個類可以有多個拷貝建構函式,既可以是public的,也可以是private的 特殊用法,如設計模式中的單例模式需要將拷貝建...

C 中的深拷貝與淺拷貝

淺拷貝 又稱值拷貝,將源物件的值拷貝到目標物件中去,本質上來說源物件和目標物件共用乙份實體,只是所引用的變數名不同,位址其實還是相同的。舉個簡單的例子,你的小名叫西西,大名叫冬冬,當別人叫你西西或者冬冬的時候你都會答應,這兩個名字雖然不相同,但是都指的是你。假設有乙個string類,string s...