【c++】9.深拷贝、浅拷贝、拷贝构造函数 、移动构造函数
深拷貝、淺拷貝、拷貝構(gòu)造函數(shù) 、移動構(gòu)造函數(shù)
關(guān)于拷貝構(gòu)造、深拷貝、淺拷貝參考https://blog.csdn.net/qq_29344757/article/details/76037255
淺拷貝只拷貝指針,不新開辟內(nèi)存。深拷貝會另外開辟一塊內(nèi)存,內(nèi)容和拷貝的對象一樣。
所謂拷貝構(gòu)造,傳入的參數(shù)限定于是同一類之前創(chuàng)建的對象,用它來初始化新建的對象。
拷貝構(gòu)造主要就是把別的對象的成員變量的值賦值給自己的成員變量?;蛘哒f,直接新開辟一段內(nèi)存,然后把傳入的對象的成員變量的值賦值給自己。并不能直接把其他對象直接復(fù)制給自己,沒有這種用法。
對于傳入的參數(shù)是例如int類型之類的構(gòu)造函數(shù),他不叫拷貝構(gòu)造函數(shù),它只是簡單的構(gòu)造函數(shù)。
默認(rèn)的拷貝構(gòu)造函數(shù),對于指針變量是淺拷貝,對于非指針變量是深拷貝。這樣在析構(gòu)時會造成double free的錯誤。所以必須自己定義拷貝構(gòu)造函數(shù),在里面對指針變量新分配內(nèi)存后,再把別的對象的指針里面的值賦給它。
默認(rèn)拷貝賦值函數(shù)也是淺拷貝。
所以類的成員變量中有指針變量時,必須對拷貝構(gòu)造函數(shù)和拷貝賦值函數(shù)重新定義。
拷貝構(gòu)造的作用是防止淺拷貝。
因為如果我們不使用深拷貝而使用淺拷貝的話,對象a淺拷貝對象b,當(dāng)淺拷貝的對象b析構(gòu)后,b所指向的內(nèi)存已經(jīng)釋放,那么a所指向的內(nèi)存也被釋放了,當(dāng)a自己再析構(gòu)的時候就析構(gòu)不了了。
還有就是淺拷貝時,任何一個對象對該值進(jìn)行修改都會影響另一個對象中的值。
默認(rèn)拷貝構(gòu)造函數(shù)定義舉例:
class A{ public: //默認(rèn)拷貝構(gòu)造函數(shù)為A(const A& a){tmp1=a.tmp1;//深拷貝,不同對象tmp1的地址不一樣ptr=a.ptr;//淺拷貝,因為ptr為指針變量}private:int tmp1;int *ptr; };我們自己需要重新定義的拷貝構(gòu)造函數(shù):
A(const A& a){tmp1=a.tmp1;//深拷貝,不同對象tmp1的地址不一樣ptr= new int;*ptr=*(a.ptr);//深拷貝,因為他們的ptr的地址不一樣了。 }移動構(gòu)造函數(shù)
移動構(gòu)造函數(shù)就是右值引用構(gòu)造函數(shù)。他是為了實現(xiàn)淺拷貝,復(fù)用其他對象中的資源(堆內(nèi)存),延長其他臨時對象的生命周期。
A(A&& a):ptr(a.ptr){a.ptr=nullptr;//調(diào)用移動構(gòu)造函數(shù),會先把a對象的指針變量ptr先賦值給自己的指針變量ptr,然后把a.ptr指向空指針,這樣a在析構(gòu)的時候就不會把a.ptr本來指向的內(nèi)容給釋放了。這樣自己的ptr指針還是指向那塊內(nèi)存。注意,指針指向的那塊內(nèi)存的值是通過*p=?的方式來修改的,所以修改指針指向并不是修改指針指向的內(nèi)存的值,不要混淆。 }另外,關(guān)于拷貝構(gòu)造函數(shù)和移動構(gòu)造函數(shù),他們傳入的形參都一樣,怎么知道調(diào)用哪個呢?程序會判斷這個形參是不是臨時對象,如果是臨時對象,就會調(diào)用移動構(gòu)造函數(shù)。
注意上面說的傳入的形參,也可以是通過類似A a=func()這種使用方式。其中
A func(){A a;return a; //返回一個臨時對象。 }所謂拷貝構(gòu)造,傳入的參數(shù)限定于是同一類之前創(chuàng)建的對象,用它來初始化新建的對象。
如果類中有指針類型的成員變量,那就必須定義拷貝構(gòu)造函數(shù),否則你讓別的對象的指針成員變量給他賦值,就是淺拷貝,有內(nèi)存風(fēng)險。
void test(int a, int b){ }test是函數(shù)的首地址,他是一個函數(shù),類型是void()。 &test表示一個指向函數(shù)test這個對象的地址,他是一個指針類型是void(*)()。 所以test和&test所代表的地址值是一樣的,但是類型不一樣。總結(jié)
以上是生活随笔為你收集整理的【c++】9.深拷贝、浅拷贝、拷贝构造函数 、移动构造函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【c++】8.map和vector容器查
- 下一篇: 【c++】14.编译proto和prot