1. 程式人生 > >C++深拷貝和淺拷貝

C++深拷貝和淺拷貝

C++中類的拷貝有兩種:深拷貝,淺拷貝:當出現類的等號賦值時,即會呼叫拷貝函式
一:兩個的區別
1  在未定義顯示拷貝建構函式的情況下,系統會呼叫預設的拷貝函式——即淺拷貝,它能夠完成成員的一一複製。當資料成員中沒有指標時,淺拷貝是可行的;但當資料成員中有指標時,如果採用簡單的淺拷貝,則兩類中的兩個指標將指向同一個地址,當物件快結束時,會呼叫兩次解構函式,而導致指標懸掛現象,所以,此時,必須採用深拷貝。
2 深拷貝與淺拷貝的區別就在於深拷貝會在堆記憶體中另外申請空間來儲存資料,從而也就解決了指標懸掛的問題。簡而言之,當資料成員中有指標時,必須要用深拷貝。
二  帶例項的解釋
c++預設的拷貝建構函式是淺拷貝
淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了一個沒有類而沒有提供它的複製建構函式,當用該類的一個物件去給令一個物件賦值時所執行的過程就是淺拷貝,如:
class A 
{ 
public:  A(int _data) : data(_data){}  A(){} private:  int data;  }; int main()  {  A a(5), b = a; // 僅僅是資料成員之間的賦值  } 這一句b = a;就是淺拷貝,執行完這句後b.data = 5; 如果物件中沒有其他的資源(如:堆,檔案,系統資源等),則深拷貝和淺拷貝沒有什麼區別, 但當物件中有這些資源時,例子: class A  {  public:  A(int _size) : size(_size) { data = new int[size]; } // 假如其中有一段動態分配的記憶體 
A(){}; ~A() { delete [] data; } // 析構時釋放資源 private:  int* data; int size;  } int main()  {  A a(5), b = a; // 注意這一句  } 這裡的b = a會造成未定義行為,因為類A中的複製建構函式是編譯器生成的,所以b = a執行的是一個淺拷貝過程。我說過淺拷貝是物件資料之間的簡單賦值,比如: b.size = a.size; b.data = a.data; // Oops! 這裡b的指標data和a的指標指向了堆上的同一塊記憶體,a和b析構時,b先把其data指向的動態分配的記憶體釋放了一次,而後a析構時又將這塊已經被釋放過的記憶體再釋放一次。對同一塊動態記憶體執行2次以上釋放的結果是未定義的,所以這將導致記憶體洩露或程式崩潰
所以這裡就需要深拷貝來解決這個問題,深拷貝指的就是當拷貝物件中有對其他資源(如堆、檔案、系統等)的引用時(引用可以是指標或引用)時,物件的另開闢一塊新的資源,而不再對拷貝物件中有對其他資源的引用的指標或引用進行單純的賦值。如: class A  {  public:  A(int _size) : size(_size) { data = new int[size]; } // 假如其中有一段動態分配的記憶體  A(){}; A(const A& _A) : size(_A.size) { data = new int[size]; } // 深拷貝  ~A() { delete [] data; } // 析構時釋放資源 private:  int* data;   int size;  } int main()  {  A a(5), b = a; // 這次就沒問題了  } 總結:深拷貝和淺拷貝的區別是在物件狀態中包含其它物件的引用的時候,當拷貝一個物件時,如果需要拷貝這個物件引用的物件,則是深拷貝,否則是淺拷貝。

相關推薦

C++本質:類的賦值運算符=的重載,以及拷貝拷貝

fin 過程 種類 解決 對象的引用 執行 面向 鏈式 alt 關鍵詞:構造函數,淺拷貝,深拷貝,堆棧(stack),堆heap,賦值運算符摘要: 在面向對象程序設計中,對象間的相互拷貝和賦值是經常進行的操作。 如果對象在申明的同時馬上進行的初始化操作,則

C++的拷貝建構函式、operator=運算子過載,拷貝拷貝、explicit關鍵字

1、在C++編碼過程中,類的建立十分頻繁。 簡單的功能,當然不用考慮太多,但是從進一步深刻理解C++的內涵,類的結構和用法,編寫更好的程式碼的角度去考慮,我們就需要用到標題所提到的這些內容。 最近,在看單例模式,覺得十分有趣,然而如果想要掌握單例模式,就必須掌握這些內容。下

C++細節 拷貝拷貝(位拷貝)詳解

前提 在物件拷貝過程中,如果沒有自定義拷貝建構函式,系統會提供一個預設的拷貝建構函式,預設的拷貝建構函式對於基本型別的成員變數,按位元組複製,對於類型別成員變數,呼叫其相應型別的拷貝建構函式。 閱讀《高質量的c c++程式設計》,第9章有這樣一段話,類似的話在《c++pr

C++拷貝拷貝

C++中類的拷貝有兩種:深拷貝,淺拷貝:當出現類的等號賦值時,即會呼叫拷貝函式一:兩個的區別 1 在未定義顯示拷貝建構函式的情況下,系統會呼叫預設的拷貝函式——即淺拷貝,它能夠完成成員的一一複製。當資料成員中沒有指標時,淺拷貝是可行的;但當資料成員中有指標時,如果採用簡單的

C++裡面的拷貝拷貝

//拷貝有兩種:深拷貝和淺拷貝 //1.結構體中的深拷貝和淺拷貝 /*   淺拷貝:編譯器僅僅拷貝了結構體的值,而沒有建立新的記憶體空間,而是共享同一塊記憶體空間 。當結構體成員中含有buf的時候,拷貝之後釋放記憶體就不會出現問題,但是如果結構體中含有指標變數

關於C#中拷貝拷貝的認識

首先說我理解的一些基本概念(若有不對,歡迎指點) 記憶體:用來儲存程式資訊的介質。 指標:指向一塊記憶體區域,通過它可以訪問該記憶體區域中儲存的程式資訊。(C#也是有指標的) 值型別:struct(整形、浮點型、decimal的內部實現都是struct)、enum、可空型別

js中的拷貝拷貝

所有 object 簡單的 col images new color 其他 java 深復制和淺復制只針對像 Object, Array 這樣的復雜對象的。簡單來說,淺復制只復制一層對象的屬性,而深復制則遞歸復制了所有層級。 深淺拷貝 的主要區別就是:復制的是引用(地址)還

python學習系列--拷貝拷貝

深拷貝 淺拷貝 copy deepcopy概念普通情下,復制一個對象是不會新開辟內存空間的,只是把新的對象名稱指向原有的內存地址,這種操作其實不是算是拷貝,只是新的引用。把新的對象置於新的內存空間中,才是拷貝。在python中,深淺拷貝的區別實際上是拷貝的深度不同。操作常見的‘=’號就是一種拷貝方式。pyth

js 中引用類型 的拷貝 拷貝的區別

而是 query reac cat 避免 string val this 臨時 一、曾經在讀JQ源碼的時候,對深拷貝算是有了一點的理解。我們在項目中是不是經常會遇到這樣的問題呢? 後臺返回一個數組對象(引用類型).次數在頁面渲染中需要對部分數據進行處理 比如:銀行卡6234

談Java中的拷貝拷貝

detail tle pac err @override 復制對象 deep har 間接   淺談Java中的深拷貝和淺拷貝(轉載) 原文鏈接: http://blog.csdn.net/tounaobun/article/details/8491392 假如說你想復制一

js的命名空間 && 單體模式 && 變量拷貝拷貝 && 頁面彈窗設計

但是 界面 ket 模式 utf 針對 col con prop 說在前面:這是我近期開發或者看書遇到的一些點,覺得還是蠻重要的。 一、為你的 JavaScript 對象提供命名空間 <!DOCTYPE html> <html> <head&

拷貝拷貝

深拷貝 淺拷貝 #include <stdio.h> int main(int argc, char *argv[]) { char *p1="123"; char *p2="123"; char *p3="456"; const char *p4="ab

python的復制,拷貝拷貝的區別(轉)

pla bsp space 數據 深拷貝 淺拷貝 deepcopy 拷貝 tro 在python中,對象賦值實際上是對象的引用。當創建一個對象,然後把它賦給另一個變量的時候,python並沒有拷貝這個對象,而只是拷貝了這個對象的引用 一般有三種方法, alist=[1,2,

python的拷貝拷貝

內存區域 需要 不可變 python3 復制 deepcopy 原始的 pen -m # 對象賦值 a = 'hello world' b = a print('a:',a,', b:',b) # a: hello world

Python-8 拷貝拷貝

water mark alt img 分享 深拷貝 所有 nag copy 淺拷貝 淺拷貝是對於一個對象的頂層拷貝通俗的理解是:拷貝了引用,並沒有拷貝內容 深拷貝 深拷貝是對於一個對象所有層次的拷貝(遞歸) 進一步理解拷貝 拷貝的其他方式 使用copy模

【轉載】圖解 Python 拷貝拷貝

div 原子 總結 但是 home 後來 idt scrip 需要 作者:田小計劃 出處:http://www.cnblogs.com/wilber2013/ Python中,對象的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時候不註意,就可能產生意外的結果。

對象的拷貝拷貝

height post ++ oid 一份 char log pac clu 在copy一個對象時(用一個對象去初始化另外一個對象),會調用類中的拷貝構造函數。如果我們自己沒有在類裏面寫拷貝構造函數,則C++編譯器會調用默認的拷貝構造函數。 淺拷貝:如果類定義的對象包含

拷貝拷貝的區別

log birt 並且 ace UNC 分享 一個 eof 發生 深拷貝和淺拷貝的區別 深拷貝和淺拷貝最根本的區別在於是否真正獲取一個對象的復制實體,和不是引用。 簡單來說 淺拷貝(shallowCopy)只是增加了一個指針指向已存在的內存地址, 深拷貝(deepCop

python的復制,拷貝拷貝的區別

一個 對象賦值 source 深拷貝 對象的引用 數據 拷貝 也會 方法 寫在前面: python中的.copy()拷貝和[:]拷貝皆為淺拷貝 在python中,對象賦值實際上是對象的引用。當創建一個對象,然後把它賦給另一個變量的時候,python並沒有拷貝這個對象,而只是

JavaScript的拷貝拷貝

復制 nsh book 並不會 turn 字符串 重要 jce 兩種 原文   簡書原文:https://www.jianshu.com/p/3d930756dd8f 大綱   前言  1、對深拷貝和淺拷貝的初步認識  2、深拷貝和淺拷貝的區別  3、淺拷貝存在的缺陷  4