C++深淺拷貝和string類的兩種寫法詳解
一、深淺拷貝
拷貝這個(gè)詞對(duì)于我們來(lái)說(shuō)應(yīng)該不陌生,比如我們平常的復(fù)制和粘貼就是拷貝;但是如果把拷貝這個(gè)詞放到C++中來(lái)說(shuō)就有一些復(fù)雜了,我們先來(lái)看一下什么是淺拷貝:
下面用字符串類來(lái)模擬實(shí)現(xiàn)。
class Astring
{
public:
//構(gòu)造函數(shù)
Astring(const char* str = "")
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
//采用淺拷貝寫的構(gòu)造函數(shù)
Astring(const Astring& s)
{
_str = s._str;
}
//析構(gòu)函數(shù)
~Astring()
{
delete[] _str;
_str = nullptr;
}
private:
char* _str;
};
int main()
{
Astring aa("hello C++");
Astring bb(aa); //這里調(diào)用拷貝構(gòu)造
return 0;
}
當(dāng)我們執(zhí)行以上程序的話就會(huì)失敗,結(jié)果如下:

分析如下圖所示:

所以我們采用淺拷貝使用同一塊空間是不行了,那么怎么辦呢?當(dāng)然是重新開一塊和別人同樣大小的空間,然后再把別人空間里面的內(nèi)容給拷貝過來(lái),而這樣就是所謂的深拷貝了;我們還是用字符串類來(lái)模擬實(shí)現(xiàn)深拷貝:
class Astring
{
public:
//構(gòu)造函數(shù)
Astring(const char* str = "")
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
//采用深拷貝寫的構(gòu)造函數(shù)
Astring(const Astring& s)
{
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
}
//析構(gòu)函數(shù)
~Astring()
{
delete[] _str;
_str = nullptr;
}
private:
char* _str;
};
int main()
{
Astring aa("hello C++");
Astring bb(aa);
return 0;
}
分析如下圖所示:

二、string類的兩種寫法
有了上面我們知道的深淺拷貝,所以我們明白類中的拷貝構(gòu)造函數(shù)和賦值重載一定要用深拷貝來(lái)實(shí)現(xiàn),不過拷貝構(gòu)造函數(shù)和賦值重載還是有兩種寫法的。
1. 傳統(tǒng)寫法
傳統(tǒng)寫法就是要自己開辟空間自己來(lái)拷貝別人的東西,什么事情都要自己干,代碼如下:
//搞一個(gè)命名空間,里面實(shí)現(xiàn)自己寫的string類
namespace cjy
{
class string
{
public:
//構(gòu)造函數(shù)
string(const char* str = "")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
//拷貝構(gòu)造函數(shù)
string(string& s)
:_str(new char[strlen(s._str) + 1])
{
strcpy(_str, s._str);
}
//賦值重載,s1=s3
string& operator=(const string& s)
{
if (this != &s)
{
char* tmp = new char[strlen(s._str) + 1];
delete[] _str;
_str = tmp;
strcpy(_str, s._str);
}
return *this;
}
//析構(gòu)函數(shù)
~string()
{
delete[] _str;
_str = nullptr;
}
private:
char* _str;
};
}
2. 現(xiàn)代寫法
現(xiàn)代寫法就是復(fù)用其它的函數(shù),自己不用干活,交給其它函數(shù)來(lái)幫你實(shí)現(xiàn),代碼如下:
//現(xiàn)代寫法:拷貝構(gòu)造、賦值重載函數(shù)
namespace cjy
{
class string
{
public:
//構(gòu)造函數(shù)
string(const char* str = "")
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
//拷貝構(gòu)造函數(shù)
string(const string& s)
:_str(nullptr)
{
string tmp(s._str);
std::swap(_str, tmp._str);
}
//賦值重載
string& operator=(string s)
{
std::swap(_str, s._str);
return *this;
}
private:
char* _str;
};
}
分析如下圖所示:


總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++?Boost?Accumulators累加器詳細(xì)講解
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱2022-11-11
C++?LeetCode1769移動(dòng)所有球到每個(gè)盒子最小操作數(shù)示例
這篇文章主要為大家介紹了C++?LeetCode1769移動(dòng)所有球到每個(gè)盒子所需最小操作數(shù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
vscode遠(yuǎn)程連接服務(wù)器(免密登錄+遠(yuǎn)程開發(fā))
vscode的遠(yuǎn)程連接功能十分方便,本文就來(lái)介紹一下vscode遠(yuǎn)程連接服務(wù)器,主要包括免密登錄和遠(yuǎn)程開發(fā),感興趣的可以了解一下2024-07-07
C語(yǔ)言入門篇--初識(shí)C語(yǔ)言及數(shù)據(jù)類型
本篇文章是c語(yǔ)言基礎(chǔ)篇,主要為大家介紹了C語(yǔ)言的基本類型,為大家介紹了什么是C語(yǔ)言,希望可以幫助大家快速入門c語(yǔ)言的世界,更好的理解c語(yǔ)言2021-08-08

