Gitlab 安裝
阿新 • • 發佈:2020-11-16
技術標籤:c++
首先我們要知道預設拷貝建構函式可以完成物件的資料成員的簡單複製,這也成為淺拷貝。物件的資料資源是由指標指向的堆時,預設的拷貝建構函式只是將指標複製。
先來看一段程式碼:
#include <iostream>
using namespace std;
class Test
{
private:
int* p;
public:
Test(int x)
{
this->p=new int(x);
cout << "物件被建立" << endl;
}
~Test()
{
if (p != NULL)
{
delete p;
}
cout << "物件被釋放" << endl;
}
int getX() { return *p; }
};
int main()
{
Test a(10);
Test b = a; //會呼叫預設的拷貝建構函式
return 0;
}
執行結果:
最後報物件被釋放了兩次的錯誤。為什麼會這樣?
Test a(10);
Test b = a; //會呼叫預設的拷貝建構函式
第一個語句建立了一個物件a(指標),指向了資料資源。這時再執行第二個語句,呼叫了預設拷貝建構函式,建立一個物件b,它只是將a的地址複製給b,所以b仍舊指向a的資料資源。那麼一旦執行解構函式,就會發現同樣的資料資源被析構了兩次。這就會出現錯誤。
要解決上面的問題,就要進行深拷貝,很簡單,就是自己寫一個拷貝建構函式
#include <iostream>
using namespace std;
class Test
{
private:
int* p;
public:
Test(int x)
{
this ->p=new int(x);
cout << "物件被建立" << endl;
}
~Test()
{
if (p != NULL)
{
delete p;
}
cout << "物件被釋放" << endl;
}
int getX() { return *p; }
//深拷貝(拷貝建構函式)
Test(const Test& a)
{
this->p = new int(*a.p);
cout << "物件被建立" << endl;
}
//淺拷貝(拷貝建構函式)
//Test(const Test& a)
//{
// this->p = a.p;
// cout << "物件被建立" << endl;
//}
};
int main()
{
Test a(10);
Test b = a; //會呼叫我們手動寫的拷貝建構函式
return 0;
}
執行結果:
這個時候就沒有出錯。
因為深拷貝會重新開闢一個記憶體空間給物件b