淺拷貝和深拷貝
在某些狀況下,類內成員變量需要動態開辟堆內存,如果實行位拷貝,也就是把對象里的值完全復制給另一個對象,如A=B。這時,如果B中有一個成員變量指針已經申請了內存,那A中的那個成員變量也指向同一塊內存。這就出現了問題:當B把內存釋放了(如:析構),這時A內的指針就是野指針了,出現運行錯誤。
深拷貝和淺拷貝可以簡單理解為:如果一個類擁有資源,當這個類的對象發生復制過程的時候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝。下面舉個深拷貝的例子。
-
-
using namespace std;
-
class CA
-
{
-
public:
-
CA( int b,char* cstr)
-
{
-
a=b;
-
str= new char[b];
-
strcpy(str,cstr);
-
}
-
CA( const CA& C)
-
{
-
a=C.a;
-
str= new char[a]; //深拷貝
-
if(str!=0)
-
strcpy(str,C.str);
-
}
-
void Show()
-
{
-
cout<<str<<endl;
-
}
-
~CA()
-
{
-
delete str;
-
}
-
private:
-
int a;
-
char *str;
-
};
-
-
int main()
-
{
-
CA A(10,"Hello!");
-
CA B=A;
-
B.Show();
-
return 0;
-
}
深拷貝和淺拷貝的定義可以簡單理解成:如果一個類擁有資源(堆,或者是其它系統資源),當這個類的對象發生復制過程的時候,這個過程就可以叫做深拷貝,反之對象存在資源,但復制過程並未復制資源的情況視為淺拷貝。
淺拷貝資源后在釋放資源的時候會產生資源歸屬不清的情況導致程序運行出錯。
CA(const CA& C)是自定義的拷貝構造函數,拷貝構造函數的名稱必須與類名稱一致,函數的形式參數是本類型的一個引用變量,且必須是引用。
當用一個已經初始化過了的自定義類類型對象去初始化另一個新構造的對象的時候,拷貝構造函數就會被自動調用,如果你沒有自定義拷貝構造函數的時候,系統將會提供給一個默認的拷貝構造函數來完成這個過程,上面代碼的復制核心語句就是通過CA(const CA& C)拷貝構造函數內的語句完成的。
(轉載自:https://blog.csdn.net/u014391177/article/details/82228662)