拷貝構造是確確實實構造乙個新的物件,並給新物件的私有成員賦上引數物件的私有成員的值,新構造的物件和引數物件位址是不一樣的,所以如果該類中有乙個私有成員是指向堆中某一塊記憶體,如果僅僅對該私有成員進行淺拷貝,那麼會出現多個指標指向堆中同一塊記憶體,這是會出現問題,如果那塊記憶體被釋放了,就會出現其他指標指向一塊被釋放的記憶體,出現未定義的值的問題,如果深拷貝,就不會出現問題,因為深拷貝,不會出現指向堆中同一塊記憶體的問題,因為每一次拷貝,都會開闢新的記憶體供物件存放其值。
下面是淺拷貝建構函式的**:
#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...
拷貝建構函式和賦值構造
為什麼空類可以建立物件呢?複製建構函式的引數可以是 const 引用,也可以是非 const 引用。一般使用前者,這樣既能以常量物件 初始化後值不能改變的物件 作為引數,也能以非常量物件作為引數去初始化其他物件。乙個類中寫兩個複製建構函式,乙個的引數是 const 引用,另乙個的引數是非 const...
建構函式 拷貝建構函式 賦值建構函式
class和struct很大乙個區別在於,c除了成員的訪問控制許可權,struct中的成員預設是public,而class中的field預設是private class還有乙個special的地方是它有建構函式 constructor。建構函式是class中的一員,和成員變數 其他成員函式一起構成乙...