昨天晚上在看智慧型指標的時候,我發現自己連乙個拷貝建構函式和賦值建構函式都寫不出來,自己就嘗試寫了乙個版本,結果發現錯誤百出,對於拷貝建構函式和賦值建構函式的理解僅僅停留在理論的方面,而不知其中太多的內涵。
比如我們都知道拷貝建構函式和賦值建構函式最大的不同在於:
拷貝構造是確確實實構造乙個新的物件,並給新物件的私有成員賦上引數物件的私有成員的值,新構造的物件和引數物件位址是不一樣的,所以如果該類中有乙個私有成員是指向堆中某一塊記憶體,如果僅僅對該私有成員進行淺拷貝,那麼會出現多個指標指向堆中同一塊記憶體,這是會出現問題,如果那塊記憶體被釋放了,就會出現其他指標指向一塊被釋放的記憶體,出現未定義的值的問題,如果深拷貝,就不會出現問題,因為深拷貝,不會出現指向堆中同一塊記憶體的問題,因為每一次拷貝,都會開闢新的記憶體供物件存放其值。
下面是淺拷貝建構函式的**:
#include using執行結果如下:namespace
std;
class
a a(
const a&a)
~a()
void
get()
};int
main()
下面是深拷貝建構函式的**:
#include #include執行截圖如下:using
namespace
std;
class
a a(
const a&a)
~a()
void
get()
};int
main()
但是賦值建構函式是將乙個引數物件中私有成員賦給乙個已經在記憶體中佔據記憶體的物件的私有成員,賦值建構函式被賦值的物件必須已經在記憶體中,否則呼叫的將是拷貝建構函式,當然賦值建構函式也有深拷貝和淺拷貝的問題。當然賦值建構函式必須能夠處理自我賦值的問題,因為自我賦值會出現指標指向乙個已經釋放的記憶體。還有賦值建構函式必須注意它的函式原型,引數必須是引用型別,返回值也必須是引用型別,否則在傳參和返回的時候都會再次呼叫一次拷貝建構函式。
#include #include執行截圖如下:using
namespace
std;
class
a a(
const a& a) //
拷貝建構函式的引數一定是引用,不能不是引用,不然會出現無限遞迴
a& operator=(const a&a) //記住形參和返回值一定要是引用型別,否則傳參和返回時會自動呼叫拷貝建構函式
n = new
int[10
]; memcpy(n, a.n,
10);
cout
<
assign constructor is called\n";
return *this
; }
~a()
void
get()
};int
main()
如果我們在賦值建構函式的形參和返回值不用引用型別,**如下:
#include #include執行截圖如下:using
namespace
std;
class
a a(
const a& a) //
拷貝建構函式的引數一定是引用,不能不是引用,不然會出現無限遞迴
a operator=(const
a a) //傳參和返回值設定錯誤
n = new
int[10
]; memcpy(n, a.n,
10);
cout
<
assign constructor is called\n";
return *this
; }
~a()
void
get()
};int
main()
return0;
}
多了兩次的拷貝建構函式的呼叫和兩次析構函式的呼叫。
對於拷貝建構函式和賦值建構函式的理解
昨天晚上在看智慧型指標的時候,我發現自己連乙個拷貝建構函式和賦值建構函式都寫不出來,自己就嘗試寫了乙個版本,結果發現錯誤百出,對於拷貝建構函式和賦值建構函式的理解僅僅停留在理論的方面,而不知其中太多的內涵。比如我們都知道拷貝建構函式和賦值建構函式最大的不同在於 拷貝構造是確確實實構造乙個新的物件,並...
對於拷貝建構函式和賦值建構函式的理解
昨天晚上在看智慧型指標的時候,我發現自己連乙個拷貝建構函式和賦值建構函式都寫不出來,自己就嘗試寫了乙個版本,結果發現錯誤百出,對於拷貝建構函式和賦值建構函式的理解僅僅停留在理論的方面,而不知其中太多的內涵。比如我們都知道拷貝建構函式和賦值建構函式最大的不同在於 拷貝構造是確確實實構造乙個新的物件,並...
拷貝建構函式和賦值建構函式
class cmystring 賦值建構函式 cmystring cmystring operator const cmystring str 新分配記憶體,將str的m pdata記憶體拷貝到m pdata中 m pdata new char strlen str.m pdata 1 strcpy...