1.什麼是淺拷貝?
概念:淺拷貝也叫位拷貝,編譯器會按照字節將對象的只拷貝過來。
適用場景:一般適用於沒有空間開闢或者釋放的情況下,默認構造函數是淺拷貝。
拷貝指針僅僅拷貝地址,而不會拷貝對應的空間,好處是減少了開闢空間和銷燬空間,但是會造成同一塊空間被多次釋放,從而使得程序崩潰。
2.什麼是深拷貝?
概念:深拷貝是開闢新的空間,將對象所指向的內容拷貝一份。
指針拷貝時,會開闢新的空間,複製一份原來指針的內容,各自有各自的空間儲存,不會造成同一塊空間被多次釋放。
3.樣例
1.這裏展示淺拷貝
namespace xff {
class string
{
public:
string(const char* str = "")
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
~string()
{
std::cout << _str <<std:: endl;
if (_str)
{
delete[] _str;
_str = nullptr;
}
}
private:
char* _str;
};
// 測試
void Teststring()
{
string s1("hello");
string s2(s1);
}
}
int main() {
xff::Teststring();
system("pause");
return 0;
}
2.結果展示
3.出現原因
通過查看內存,我們發現s1和s2的指針指向同一塊空間,那麼在析構的時候,s2先析構直接把_str對應的空間釋放了,當s1再次調用析構函數時,會出現程序崩潰的問題。
4.解決辦法(深拷貝)
1.代碼展示
namespace xff {
class string
{
public:
string(const char* str = "")
{
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
string(const string& s)
:_str(nullptr)
{
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
}
~string()
{
std::cout << _str <<std:: endl;
if (_str)
{
delete[] _str;
_str = nullptr;
}
}
private:
char* _str;
};
// 測試
void Teststring()
{
string s1("hello");
string s2(s1);
}
}
int main() {
xff::Teststring();
system("pause");
return 0;
}
2.結果展示
3.內存查看
4.總結
我們通過查看內存發現s1和s2的內容雖然相同,但是地址卻不同,在析構的時候互相不干擾,就不會出現同一塊空間多次釋放的問題。