程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++學習之拷貝構造函數篇

C++學習之拷貝構造函數篇

編輯:C++入門知識

C++學習之拷貝構造函數篇


一、拷貝構造函數的聲明

Array(const Array & arr);

二、拷貝構造函數的實現分為兩種,即是深拷貝和淺拷貝。

1.淺拷貝

代碼如下:

class Array

{

public:

Array()

{

m_iCount = 5;

m_pArr = new int[m_iCount];

}

Array(const Array& arr)

{

m_iCount = arr. m_iCount;

m_pArr = arr.m_pArr;

}

private:

int m_iCount;

int * m_pArr;

}

int main(void)

{

Array arr1;

Array arr2 = arr1;

return 0;

}

這種簡單的淺拷貝將會使arr1和arr2裡面的m_pArr成員的值是一樣的,即指向的內存地址是一樣的。如下圖所示。此時,如果先給arr1的m_pArr賦了一些值,也就是在內存地址0x00FF00這段內存中寫了一些值,然後再給arr2的m_pArr再賦值的時候,那麼同一段內存將會被重寫,而覆蓋掉之前arr1的m_pArr所賦進去的值。更嚴重的是當我們銷毀arr1這個對象的時候,我們為了避免內存洩露,肯定會釋放m_pArr所指向的這段內存。如果我們已經釋放掉了這段內存,再去銷毀arr2對象的時候,肯定也會以同樣的方式再釋放掉arr2裡面的m_pArr所指向的這段內存,這樣同一段內存將被釋放兩次,計算機會以崩潰的方式抗議,與語法錯誤的提示信息是不一樣的,難以查找出錯根源。

2.深拷貝

因此,我們希望拷貝構造函數所完成的工作是這樣的,如下圖所示。兩個對象的指針所指向的應該是不同的內存,拷貝的時候不應該是將指針的地址簡單地拷貝過來,而是將指針所指向的地址中存儲的每一個元素依次地拷貝過來,這個才是我們真正想要的效果,這個過程就是深拷貝。

代碼如下:

class Array

{

public:

Array()

{

m_iCount = 5;

m_pArr = new int[m_iCount];

}

Array(const Array& arr)

{

m_iCount = arr. m_iCount;

m_pArr = new int[m_iCount];

for(int i=0;i

{

m_pArr[i] = arr.m_pArr[i];

}

 

 

//m_pArr = arr.m_pArr;

}

private:

int m_iCount;

int * m_pArr;

}

int main(void)

{

Array arr1;

Array arr2 = arr1;

return 0;

}

 

3.總結:

當進行對象拷貝時,不是簡單地進行值得拷貝,而是將堆中內存的數據也進行拷貝,這種拷貝方式就叫做深拷貝,只進行值得拷貝的方式叫做淺拷貝。深淺拷貝具有以下特點:

(1)當數據成員中含有指針時,淺拷貝會使兩個對象的成員指針指向相同的地址,這個時候會導致地址重復刪除或被重新賦值。

(2)不是所有的對象都需要深拷貝,應該根據情況合理使用。

(3)深拷貝不是簡單的值拷貝,而是重新分配同樣大小的內存地址,將指針成員指向的內存數據進行拷貝。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved