網站首頁 編程語言 正文
文章簡述
c++中構造函數分為三類:無參構造、帶參構造和拷貝構造,其中拷貝構造可分為默認拷貝(淺拷貝)、深拷貝,在程序中,這里我們主要講淺拷貝和深拷貝的聯系和區別。
首先,我們要明白拷貝至少需要兩個對象,并且在拷貝時,我們可以用const來保護原對象的內容,具體用法:----- <類名>(const<類名> 對象) -----進行復制的對象 ,當我們使用棧開辟空間進行復制時,不會出現意外,如下:
/*===============================================
* 文件名稱:shallow_deep_copy.cpp
* 創 建 者:
* 創建日期:
* 描 述:
================================================*/
#include <iostream>
using namespace std;
class student
{
private:
string name; //--------------//
int age;
public:
student() //出現帶參構造,需要默認構造
{
cout << "默認構造" << endl;
}
student(string m_name, int m_age)
{
cout << "name:" << m_name << endl << "age:" << m_age << endl;
cout << "帶參構造" << endl;
}
~student()
{
cout << "析構函數" << endl;
}
};
void test1()
{
student s1 = student("tom", 12);
student s2 = s1; //利用棧進行默認復制
}
int main()
{
test1(); //引用函數.
return 0;
}
結果如圖:
name:tom
age:12
帶參構造
析構函數
析構函數
我們可以發現,復制后進行輸出時只有一個帶參構造和兩個析構函數,說明了棧中系統自動申請又釋放了兩次空間,但是這個操作卻在自己創建空間(堆)時,卻是錯誤的,此時的代碼又有所不同:
/*===============================================
* 文件名稱:shallow_deep_copy.cpp
* 創 建 者:
* 創建日期:
* 描 述:
================================================*/
#include <iostream>
using namespace std;
class student
{
private:
string name;
//int age;
int *age; //定義指針age
public:
student()
{
cout << "默認構造" << endl;
}
#if 0 //------------------------------------------
student(string m_name, int m_age)
{
cout << "name:" << m_name << endl << "age:" << m_age << endl;
cout << "帶參構造" << endl;
}
#endif //-------------------------------------------
student(int m_age)
{
this->age = new int(m_age);
cout << "開辟空間" << endl;
}
~student()
{
delete age; //開辟使用完成,在析構進行釋放age操作
cout << "析構函數" << endl;
}
int get_age()
{
return *age;
}
};
void test1()
{
//student s1 = student("tom", 12);
//student s2 = s1;
student s1(10); //定義年齡為10,進行復制
student s2 = s1;
}
int main()
{
test1(); //調用函數
return 0;
}
結果:
開辟空間
析構函數
free(): double free detected in tcache 2
已放棄 (核心已轉儲)
這里我們只調用了*age這個參數,但已經很明顯的看到結果,錯誤信息為兩次釋放該空間,在開辟這片空間時,又進行重復釋放操作,很明顯這是系統所不允許的。
接下來進行深拷貝:
/*===============================================
* 文件名稱:shallow_deep_copy.cpp
* 創 建 者:
* 創建日期:
* 描 述:
================================================*/
#include <iostream>
using namespace std;
class student
{
private:
string name;
//int age;
int *age;
public:
student()
{
cout << "默認構造" << endl;
}
#if 0 //--------------------------------------
student(string m_name, int m_age)
{
cout << "name:" << m_name << endl << "age:" << m_age << endl;
cout << "帶參構造" << 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); //創建一片新的空間進行儲存
cout << "深拷貝" << endl;
}
//--------------------------------------
~student()
{
delete age;
cout << "析構函數" << 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;
}
開辟空間
深拷貝
析構函數
析構函數
此時結果為正確,這里釋放的是兩片一樣內容但地址不一樣的空間。
到此,*我們就能總結出:淺拷貝(默認拷貝)是兩個指針申請同一片空間地址,而在釋放時,也是同一片堆內存;深拷貝是對指針所指向的內容進行拷貝,同時兩個指針指向的是不同空間地址,所以在釋放時需要釋放兩次。
原文鏈接:https://blog.csdn.net/qq_48866804/article/details/126692936
相關推薦
- 2023-01-28 ajax、axios和fetch之間優缺點重點對比總結_AJAX相關
- 2022-06-28 python神經網絡使用tensorflow實現自編碼Autoencoder_python
- 2022-06-28 一文搞懂Python中的進程,線程和協程_python
- 2022-05-10 git reset中hard與soft區別
- 2022-07-20 C語言深入刨析數據結構之棧與鏈棧的設計與應用_C 語言
- 2022-10-29 node-sass安裝失敗解決方法
- 2022-04-09 SpringBoot 動態過濾自動配置類
- 2022-04-20 appium中常見的幾種點擊方式_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支