C++中的拷貝構(gòu)造詳解
拷貝構(gòu)造函數(shù)
同一個(gè)類的對(duì)象在內(nèi)存中有完全相同的結(jié)構(gòu),如果作為一個(gè)整體進(jìn)行復(fù)制或稱拷貝是完美可行的,這個(gè)拷貝過(guò)程只需要拷貝數(shù)據(jù)成員,而函數(shù)成員是公用的(只有一份代碼);在建立對(duì)象時(shí)可用同一類的另一個(gè)對(duì)象來(lái)初始化該對(duì)象的存儲(chǔ)空間,這時(shí)所用的構(gòu)造函數(shù)稱為拷貝構(gòu)造函數(shù)
例如:
class Object
{
int value;
public:
Object(int x = 0) :value(x) {}
~Object() {}
Object(Object& obj):value(obj.value)
{
cout << "Copy Create" << endl;
}
};
int main()
{
Object obja(10);
Object objb(obja);//一個(gè)對(duì)象初始化另一個(gè)對(duì)象空間,調(diào)用拷貝構(gòu)造
}
當(dāng)一個(gè)對(duì)象去初始化另一個(gè)對(duì)象空間,調(diào)用拷貝構(gòu)造;若類中沒(méi)有寫拷貝構(gòu)造,如同構(gòu)造函數(shù)與析構(gòu)函數(shù)一樣,系統(tǒng)會(huì)生成一個(gè)缺省的拷貝構(gòu)造函數(shù)
OBject(Object& obj)
{}
拷貝構(gòu)造中的引用
如果我們?cè)趯懙目截悩?gòu)造不加引用,這樣會(huì)引起死遞歸
//Object(Object& obj):value(obj.value)
Object(Object obj):value(obj.value)
{
cout << "Copy Create" << endl;
}
為什么拷貝構(gòu)造函數(shù)必須采用引用傳參,否則會(huì)引發(fā)無(wú)窮遞歸呢?
這個(gè)問(wèn)題其實(shí)很簡(jiǎn)單,再?gòu)?fù)制對(duì)象時(shí)要分為兩個(gè)步驟:
第一步:開(kāi)辟一個(gè)臨時(shí)空間;
第二步:由于臨時(shí)空間是需要構(gòu)造的,重新調(diào)用拷貝構(gòu)造函數(shù)(無(wú)窮遞歸形成…)
同時(shí)我們可以在拷貝構(gòu)造參數(shù)前加上一個(gè)引用,來(lái)限制可能會(huì)出現(xiàn)的問(wèn)題
//Object(Object& obj):value(obj.value)
Object(const Object& obj):value(obj.value)
{
cout << "Copy Create" << endl;
}
//這里的const修飾,令我們不能修改被拷貝對(duì)象
什么情況會(huì)使用拷貝構(gòu)造
拷貝構(gòu)造不止在使用一個(gè)對(duì)象去構(gòu)造另一個(gè)對(duì)象時(shí)調(diào)用,在下面這些情況也會(huì)調(diào)用:
class Object{int value;public:Object(){cout << "Object::Object" << this << endl;}Object(int x = 0) :value(x){cout << "Object::Object" << this << endl;}~Object(){cout << "Objecet::~Object" << this << endl;}Object(Object& obj) :value(obj.value){cout << "Copy Create" << this << endl;}void SetValue(int x) { value = x; }int GetValue() const { return value; }};Object fun(Object obj){int val = obj.GetValue();Object obja(val);return obja;}int main(){Object objx(0);Object objy(0);objy = fun(objx);return 0;}class Object
{
int value;
public:
Object()
{
cout << "Object::Object" << this << endl;
}
Object(int x = 0) :value(x)
{
cout << "Object::Object" << this << endl;
}
~Object()
{
cout << "Objecet::~Object" << this << endl;
}
Object(Object& obj) :value(obj.value)
{
cout << "Copy Create" << this << endl;
}
void SetValue(int x) { value = x; }
int GetValue() const { return value; }
};
Object fun(Object obj)
{
int val = obj.GetValue();
Object obja(val);
return obja;
}
int main()
{
Object objx(0);
Object objy(0);
objy = fun(objx);
return 0;
}
在上面這一段代碼中,我們總共創(chuàng)建了幾個(gè)對(duì)象呢,我們來(lái)看一下

首先①②屬于對(duì)象的構(gòu)造,調(diào)用構(gòu)造函數(shù);程序運(yùn)行到objy = fun(objx);進(jìn)入到fun函數(shù),這是構(gòu)造臨時(shí)對(duì)象obj③屬于拷貝構(gòu)造;隨后④構(gòu)造對(duì)象obja;最后⑤這里也屬于拷貝構(gòu)造也需要?jiǎng)?chuàng)建一個(gè)臨時(shí)對(duì)象(將亡值)
并且我們無(wú)法將fun函數(shù)中obja對(duì)象之間return傳回給objy,因?yàn)樵诤瘮?shù)結(jié)束時(shí)obja會(huì)析構(gòu)失效,所以這里會(huì)創(chuàng)建一個(gè)新的臨時(shí)對(duì)象

總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語(yǔ)言二叉樹(shù)與堆的概念與實(shí)現(xiàn)
這篇文章主要給大家介紹了關(guān)于C語(yǔ)言二叉樹(shù)與堆的相關(guān)資料,文章詳細(xì)記錄了他們的相關(guān)概念以及如何實(shí)現(xiàn)的,通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2021-06-06
C++?Opencv實(shí)現(xiàn)錄制九宮格視頻
這篇文章主要為大家介紹了如何利用C++和OpenCV庫(kù)實(shí)現(xiàn)錄制九宮格視頻,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,感興趣的可以了解一下2022-05-05
C++基于字符串實(shí)現(xiàn)大數(shù)相乘問(wèn)題的代碼詳解
在實(shí)際編程中,我們經(jīng)常會(huì)遇到需要處理大整數(shù)的情況,由于編程語(yǔ)言中內(nèi)置整數(shù)類型有其表示范圍的限制,當(dāng)需要處理的整數(shù)超出這些范圍時(shí),就不能直接使用內(nèi)置類型進(jìn)行計(jì)算,所以本文給大家介紹了相關(guān)的解決方法,需要的朋友可以參考下2025-03-03
C++設(shè)計(jì)模式編程中proxy代理模式的使用實(shí)例
這篇文章主要介紹了C++設(shè)計(jì)模式編程中proxy代理模式的使用實(shí)例解析,代理模式可以被歸類為結(jié)構(gòu)型的設(shè)計(jì)模式,代理模式主張為對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn),需要的朋友可以參考下2016-03-03
Linux/C++多線程實(shí)例學(xué)習(xí)十字路口車輛調(diào)度
這篇文章主要為大家介紹了Linux/C++多線程實(shí)例學(xué)習(xí)十字路口車輛調(diào)度示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

