淺析C++淺拷貝與深拷貝的聯(lián)系和區(qū)別
文章簡述
c++中構(gòu)造函數(shù)分為三類:無參構(gòu)造、帶參構(gòu)造和拷貝構(gòu)造,其中拷貝構(gòu)造可分為默認(rèn)拷貝(淺拷貝)、深拷貝,在程序中,這里我們主要講淺拷貝和深拷貝的聯(lián)系和區(qū)別。
首先,我們要明白拷貝至少需要兩個對象,并且在拷貝時,我們可以用const來保護原對象的內(nèi)容,具體用法:----- <類名>(const<類名> 對象) -----進行復(fù)制的對象 ,當(dāng)我們使用棧開辟空間進行復(fù)制時,不會出現(xiàn)意外,如下:
/*===============================================
* 文件名稱:shallow_deep_copy.cpp
* 創(chuàng) 建 者:
* 創(chuàng)建日期:
* 描 述:
================================================*/
#include <iostream>
using namespace std;
class student
{
private:
string name; //--------------//
int age;
public:
student() //出現(xiàn)帶參構(gòu)造,需要默認(rèn)構(gòu)造
{
cout << "默認(rèn)構(gòu)造" << endl;
}
student(string m_name, int m_age)
{
cout << "name:" << m_name << endl << "age:" << m_age << endl;
cout << "帶參構(gòu)造" << endl;
}
~student()
{
cout << "析構(gòu)函數(shù)" << endl;
}
};
void test1()
{
student s1 = student("tom", 12);
student s2 = s1; //利用棧進行默認(rèn)復(fù)制
}
int main()
{
test1(); //引用函數(shù).
return 0;
}結(jié)果如圖:
name:tom
age:12
帶參構(gòu)造
析構(gòu)函數(shù)
析構(gòu)函數(shù)
我們可以發(fā)現(xiàn),復(fù)制后進行輸出時只有一個帶參構(gòu)造和兩個析構(gòu)函數(shù),說明了棧中系統(tǒng)自動申請又釋放了兩次空間,但是這個操作卻在自己創(chuàng)建空間(堆)時,卻是錯誤的,此時的代碼又有所不同:
/*===============================================
* 文件名稱:shallow_deep_copy.cpp
* 創(chuàng) 建 者:
* 創(chuàng)建日期:
* 描 述:
================================================*/
#include <iostream>
using namespace std;
class student
{
private:
string name;
//int age;
int *age; //定義指針age
public:
student()
{
cout << "默認(rèn)構(gòu)造" << endl;
}
#if 0 //------------------------------------------
student(string m_name, int m_age)
{
cout << "name:" << m_name << endl << "age:" << m_age << endl;
cout << "帶參構(gòu)造" << endl;
}
#endif //-------------------------------------------
student(int m_age)
{
this->age = new int(m_age);
cout << "開辟空間" << endl;
}
~student()
{
delete age; //開辟使用完成,在析構(gòu)進行釋放age操作
cout << "析構(gòu)函數(shù)" << endl;
}
int get_age()
{
return *age;
}
};
void test1()
{
//student s1 = student("tom", 12);
//student s2 = s1;
student s1(10); //定義年齡為10,進行復(fù)制
student s2 = s1;
}
int main()
{
test1(); //調(diào)用函數(shù)
return 0;
}結(jié)果:
開辟空間
析構(gòu)函數(shù)
free(): double free detected in tcache 2
已放棄 (核心已轉(zhuǎn)儲)
這里我們只調(diào)用了*age這個參數(shù),但已經(jīng)很明顯的看到結(jié)果,錯誤信息為兩次釋放該空間,在開辟這片空間時,又進行重復(fù)釋放操作,很明顯這是系統(tǒng)所不允許的。
接下來進行深拷貝:
/*===============================================
* 文件名稱:shallow_deep_copy.cpp
* 創(chuàng) 建 者:
* 創(chuàng)建日期:
* 描 述:
================================================*/
#include <iostream>
using namespace std;
class student
{
private:
string name;
//int age;
int *age;
public:
student()
{
cout << "默認(rèn)構(gòu)造" << endl;
}
#if 0 //--------------------------------------
student(string m_name, int m_age)
{
cout << "name:" << m_name << endl << "age:" << m_age << endl;
cout << "帶參構(gòu)造" << endl;
}
#endif //--------------------------------------
student(int m_age)
{
this->age = new int(m_age);
cout << "開辟空間" << endl;
}
//-----------深淺拷貝-------------------
//student(const student &s)
//{
// this->age = s.age;
// cout << "淺拷貝" << endl;
//
//}
student(const student &s)
{
this->age = new int(*s.age); //創(chuàng)建一片新的空間進行儲存
cout << "深拷貝" << endl;
}
//--------------------------------------
~student()
{
delete age;
cout << "析構(gòu)函數(shù)" << endl;
}
int get_age()
{
return *age;
}
};
void test1()
{
//student s1 = student("tom", 12);
//student s2 = s1;
student s1(10);
student s2 = s1;
}
int main()
{
test1();
return 0;
}開辟空間
深拷貝
析構(gòu)函數(shù)
析構(gòu)函數(shù)
此時結(jié)果為正確,這里釋放的是兩片一樣內(nèi)容但地址不一樣的空間。
到此,*我們就能總結(jié)出:淺拷貝(默認(rèn)拷貝)是兩個指針申請同一片空間地址,而在釋放時,也是同一片堆內(nèi)存;深拷貝是對指針?biāo)赶虻膬?nèi)容進行拷貝,同時兩個指針指向的是不同空間地址,所以在釋放時需要釋放兩次。
到此這篇關(guān)于淺析C++淺拷貝與深拷貝的聯(lián)系和區(qū)別的文章就介紹到這了,更多相關(guān)C++淺拷貝與深拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言編程數(shù)據(jù)結(jié)構(gòu)帶頭雙向循環(huán)鏈表全面詳解
這篇文章主要為大家介紹了C語言編程的數(shù)據(jù)結(jié)構(gòu)中帶頭雙向循環(huán)鏈表全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進步,早日升職加薪2021-10-10
詳解QListWidget如何實現(xiàn)自定義Item效果
這篇文章主要為大家介紹了如何通過QListWidget實現(xiàn)自定義Item效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-04-04
用C/C++代碼檢測ip能否ping通(配合awk和system可以做到批量檢測)
今天小編就為大家分享一篇關(guān)于用C/C++代碼檢測ip能否ping通(配合awk和system可以做到批量檢測),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04
詳解C++標(biāo)準(zhǔn)庫中處理正則表達(dá)式的類std::regex
std?是?C++?標(biāo)準(zhǔn)庫的命名空間,包含了大量標(biāo)準(zhǔn)的?C++?類、函數(shù)和對象,這些類和函數(shù)提供了廣泛的功能,包括輸入輸出、容器、算法、字符串處理等,這篇文章主要介紹了C++標(biāo)準(zhǔn)庫中提供的用于處理正則表達(dá)式的類std::regex,需要的朋友可以參考下2024-03-03

