淺拷貝與深拷貝
? ? ? ?我們通過代碼來解釋什么是淺拷貝经伙,什么是深拷貝。
- 首先,寫一個類Person帕膜,設(shè)置無參構(gòu)造函數(shù)枣氧,有參構(gòu)造函數(shù),析構(gòu)函數(shù)垮刹,姓名char*m_Name达吞,年齡int m_age ,編譯器自動提供拷貝構(gòu)造函數(shù)荒典。
- 有參構(gòu)造函數(shù)中傳入?yún)?shù)(const char* name酪劫,int age),有參構(gòu)造函數(shù)在設(shè)置const char* 時需要開辟堆空間來存儲寺董。因此覆糟,析構(gòu)函數(shù)中需要將開辟的堆空間給free掉。
- 當(dāng)主調(diào)函數(shù)中設(shè)置了拷貝構(gòu)造函數(shù)時遮咖,生成的p2與p1是相同的滩字,兩個類對象中所存儲的內(nèi)容是一樣的,第一個屬性是char *御吞,指針類型麦箍,指向某個地址,第二個屬性是int,存儲的是個數(shù)陶珠。兩個類對象都指向相同的地址挟裂。
- 當(dāng)析構(gòu)函數(shù)free掉p1所指向的地址開辟的堆空間后,p2就找不到對應(yīng)的地址了揍诽,p2的析構(gòu)函數(shù)就會因此崩掉诀蓉。這就是淺拷貝,僅僅是簡單地復(fù)制寝姿。
- 要解決這個問題交排,就是深拷貝的方法划滋。自己提供拷貝構(gòu)造函數(shù)饵筑,設(shè)置拷貝構(gòu)造函數(shù)不僅僅是簡單地拷貝值,而是為新的拷貝開辟新的堆空間处坪,這樣兩個類對象在析構(gòu)函數(shù)free時就不會有錯誤了根资。
代碼如下:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person
{
public:
//構(gòu)造函數(shù)
Person() {}
//有參構(gòu)造函數(shù)
Person(const char* name, int age)
{
//姓名需要開辟堆空間
m_Name = (char*)malloc(strlen(name)+1);
strcpy(m_Name, name);
m_age = age;
}
//拷貝構(gòu)造函數(shù) 系統(tǒng)提供默認(rèn)拷貝構(gòu)造,值拷貝
//深拷貝同窘,自己提供拷貝構(gòu)造函數(shù)玄帕。因?yàn)闇\拷貝導(dǎo)致析構(gòu)函數(shù)兩次free
Person(const Person& p)
{
m_age = p.m_age;
//開辟新的堆空間,
m_Name = (char*)malloc(strlen(p.m_Name) + 1);
strcpy(m_Name, p.m_Name);
}
//析構(gòu)函數(shù)
~Person()
{
cout << "析構(gòu)函數(shù)調(diào)用" << endl;
//有參構(gòu)造函數(shù)開辟了堆空間,需要free
if (m_Name != NULL)
{
free(m_Name);
m_Name = NULL;
}
}
//姓名
char* m_Name;
//年齡
int m_age;
};
void test01()
{
Person p1("lol", 10);
Person p2(p1); //調(diào)用了拷貝構(gòu)造
}
int main()
{
test01();
return 0;
}
? ? ? ? 關(guān)注公號【開發(fā)小鴿】想邦,獲取海量計(jì)算機(jī)視覺與深度學(xué)習(xí)資源裤纹,實(shí)戰(zhàn)項(xiàng)目源碼,最新論文下載,大廠面試經(jīng)驗(yàn)Sソ贰N啤!?