先考慮一種情況,對乙個已知物件進行拷貝,編譯系統會自動呼叫一種建構函式——拷貝建構函式,如果使用者未定義拷貝建構函式,則會呼叫預設拷貝建構函式。
#include
#include
"student.h"
intmain()
#ifndef student_h
#define
student_h
class
student ;
#endif
#include
"student.h"
#include
using
namespace
std;
student::student()
student::~student()
執行結果:呼叫一次建構函式,呼叫兩次析構函式,兩個物件的指標成員所指記憶體相同,這會導致什麼問題呢?
name
指標被分配一次記憶體,但是程式結束時該記憶體卻被釋放了兩次
,會造成
記憶體洩漏
問題!
這是由於編譯系統在我們沒有自己定義拷貝建構函式時,會在拷貝物件時呼叫預設拷貝建構函式
,進行的是淺拷貝!即
對指標name拷貝後會出現兩個指標指向同乙個記憶體空間。
所以,在對含有指標成員的物件進行拷貝時,必須要自己定義拷貝建構函式,使拷貝後的物件指標成員有自己的記憶體空間
,即進行深拷貝,這樣就避免了記憶體洩漏發生。
自己定義拷貝建構函式: 1
2 34 5
6 78 9
10 11
12 13
14 15
16 #ifndef student_h
#define student_h
class
student
; #endif
#include
"student.h"
#include
#include <
string
.h>
using
namespace
std
student::student()
student::~student()
student::student(
const
student &s)
執行結果:呼叫一次建構函式,一次自定義拷貝建構函式,兩次析構函式。兩個物件的指標成員所指記憶體不同。
總結:淺拷貝只是對指標的拷貝,拷貝後兩個指標指向同乙個記憶體空間,深拷貝不但對指標進行拷貝,而且對指標指向的內容進行拷貝,經深拷貝後的指標是指向兩個不同位址的指標。
再說幾句:
當物件中存在指標成員時,除了在複製物件時需要考慮自定義拷貝建構函式,還應該考慮以下兩種情形:
1.當函式的引數為物件時
,實參傳遞給形參的實際上是實參的乙個拷貝物件,系統自動通過拷貝建構函式實現;
2.當函式的返回值為乙個物件時
,該物件實際上是函式內物件的乙個拷貝,用於返回函式呼叫處。
深拷貝和淺拷貝
淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了乙個沒有類而沒有提供它的複製建構函式,當用該類的乙個物件去給令乙個物件賦值時所執行的過程就是淺拷貝,如 class a a private int data int main 這一句b a 就是淺拷貝,執行完這句後b.data 5 如果物件中沒有其他...
淺拷貝和深拷貝
以下情況都會呼叫拷貝建構函式 乙個物件以值傳遞的方式傳入函式體 例如 已知class a,class b void func a a void func a a func b b 此時函式對b的操作是呼叫拷貝建構函式後的臨時拷貝物件。多數傳指標 乙個物件以值傳遞的方式從函式返回 如 return b...
深拷貝和淺拷貝
ios提供了copy和mutablecopy方法,顧名思義,copy就是複製了乙個imutable的物件,而mutablecopy就是複製了乙個mutable的物件。以下將舉幾個例子來說明。1 系統的非容器類物件 這裡指的是nsstring nsnumber等等一類的物件。nsstring stri...