日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【c++】9.深拷贝、浅拷贝、拷贝构造函数 、移动构造函数

發布時間:2025/3/21 c/c++ 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【c++】9.深拷贝、浅拷贝、拷贝构造函数 、移动构造函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

深拷貝、淺拷貝、拷貝構造函數 、移動構造函數

關于拷貝構造、深拷貝、淺拷貝參考https://blog.csdn.net/qq_29344757/article/details/76037255
淺拷貝只拷貝指針,不新開辟內存。深拷貝會另外開辟一塊內存,內容和拷貝的對象一樣。

所謂拷貝構造,傳入的參數限定于是同一類之前創建的對象,用它來初始化新建的對象。

拷貝構造主要就是把別的對象的成員變量的值賦值給自己的成員變量。或者說,直接新開辟一段內存,然后把傳入的對象的成員變量的值賦值給自己。并不能直接把其他對象直接復制給自己,沒有這種用法。

對于傳入的參數是例如int類型之類的構造函數,他不叫拷貝構造函數,它只是簡單的構造函數。

默認的拷貝構造函數,對于指針變量是淺拷貝,對于非指針變量是深拷貝。這樣在析構時會造成double free的錯誤。所以必須自己定義拷貝構造函數,在里面對指針變量新分配內存后,再把別的對象的指針里面的值賦給它。
默認拷貝賦值函數也是淺拷貝。
所以類的成員變量中有指針變量時,必須對拷貝構造函數和拷貝賦值函數重新定義。

拷貝構造的作用是防止淺拷貝。
因為如果我們不使用深拷貝而使用淺拷貝的話,對象a淺拷貝對象b,當淺拷貝的對象b析構后,b所指向的內存已經釋放,那么a所指向的內存也被釋放了,當a自己再析構的時候就析構不了了。
還有就是淺拷貝時,任何一個對象對該值進行修改都會影響另一個對象中的值。

默認拷貝構造函數定義舉例:

class A{ public: //默認拷貝構造函數為A(const A& a){tmp1=a.tmp1;//深拷貝,不同對象tmp1的地址不一樣ptr=a.ptr;//淺拷貝,因為ptr為指針變量}private:int tmp1;int *ptr; }

我們自己需要重新定義的拷貝構造函數:

A(const A& a){tmp1=a.tmp1;//深拷貝,不同對象tmp1的地址不一樣ptr= new int;*ptr=*(a.ptr);//深拷貝,因為他們的ptr的地址不一樣了。 }
移動構造函數

移動構造函數就是右值引用構造函數。他是為了實現淺拷貝,復用其他對象中的資源(堆內存),延長其他臨時對象的生命周期。

A(A&& a):ptr(a.ptr){a.ptr=nullptr;//調用移動構造函數,會先把a對象的指針變量ptr先賦值給自己的指針變量ptr,然后把a.ptr指向空指針,這樣a在析構的時候就不會把a.ptr本來指向的內容給釋放了。這樣自己的ptr指針還是指向那塊內存。注意,指針指向的那塊內存的值是通過*p=?的方式來修改的,所以修改指針指向并不是修改指針指向的內存的值,不要混淆。 }

另外,關于拷貝構造函數和移動構造函數,他們傳入的形參都一樣,怎么知道調用哪個呢?程序會判斷這個形參是不是臨時對象,如果是臨時對象,就會調用移動構造函數。

注意上面說的傳入的形參,也可以是通過類似A a=func()這種使用方式。其中

A func(){A a;return a; //返回一個臨時對象。 }

所謂拷貝構造,傳入的參數限定于是同一類之前創建的對象,用它來初始化新建的對象。

如果類中有指針類型的成員變量,那就必須定義拷貝構造函數,否則你讓別的對象的指針成員變量給他賦值,就是淺拷貝,有內存風險。

void test(int a, int b){ }test是函數的首地址,他是一個函數,類型是void()。 &test表示一個指向函數test這個對象的地址,他是一個指針類型是void(*)()。 所以test和&test所代表的地址值是一樣的,但是類型不一樣。

總結

以上是生活随笔為你收集整理的【c++】9.深拷贝、浅拷贝、拷贝构造函数 、移动构造函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。