無論是c++自定義的類還是stl內部的容器類,會顯式的定義類的物件在拷貝、賦值和銷毀時執行的操作,乙個類通過五個成員函式來控制這些操作:拷貝建構函式、拷貝賦值運算子、移動建構函式、移動賦值運算子和析構函式。其中,拷貝建構函式和移動建構函式定義了當用相同型別的乙個物件初始化另乙個物件時的操作,拷貝賦值運算子和移動賦值運算子定義類用乙個物件給另乙個相同型別的物件賦值時的操作,析構函式定義了類的物件被銷毀時的操作。
上述五個成員函式如果沒有自定義、那麼,編譯器將會在必要的時候自動定義這些操作,但是編譯器定義的版本可能並不是實際想要的
本文先介紹拷貝建構函式,拷貝賦值運算子和析構函式後面再說
一、拷貝建構函式
1、定義
在之前一系列的stl的相關的文章中,已經多多少少接觸到了拷貝建構函式。拷貝建構函式也是建構函式,只不過拷貝建構函式的引數是所在類的型別的引用,且其他引數都有預設值
示例
class test
當建立乙個test的物件時,編譯器提示找不到預設建構函式,所以,定義拷貝建構函式時,一定要定義預設建構函式2.拷貝建構函式的呼叫時機
時機1:在拷貝初始化乙個非引用引數時,會呼叫拷貝建構函式
時機2:當乙個函式的形參是非引用型別時,初始化形參的時候會呼叫拷貝建構函式(包括使用容器的insert或者push_back或者push操作)
時機3:當乙個函式用返回值初始化乙個非引用型別的物件時,會呼叫拷貝建構函式
時機4:直接建立物件時,會呼叫拷貝建構函式(這點和直接初始化相同,類的物件直接初始化實際上是匹配對應的建構函式,可是此時能匹配的只有拷貝建構函式,所以,依然會呼叫拷貝建構函式)
示例
class test
;hasptr::hasptr(const string &s)
:ps(new string(s)),
i(0)
;hasptr::hasptr(const string &s)
:sps(make_shared(s)),
i(0)
;hasptr::hasptr(const string &s)
:ps(new string(s)),
i(0)
hasptr::~hasptr()
{ cout<<__func__ alt="" height="159" src="" width="692">
在重新實現拷貝建構函式時,ps重新指向的了乙個新的string物件,只不過這個string物件的值是ps指向的值,所以,hp和hp1的ps成員分別指向兩個不同的物件,而不再指向同乙個物件,所以delete其中乙個對另乙個沒有影響
上述兩種方式推薦用第一種,有了智慧型指標之後,程式中最好不要出現普通指標。如果類的成員中一定要存在普通指標,那麼請一定要自己實現拷貝建構函式參考
《c++ primer》
C 物件導向知識點三 拷貝建構函式
拷貝建構函式是一種特殊的建構函式,它在建立物件時,是使用同一類中之前建立的物件來初始化新建立的物件。拷貝建構函式通常用於 如果在類中沒有定義拷貝建構函式,編譯器會自行定義乙個。如果類帶有指標變數,並有動態記憶體分配,則它必須有乙個拷貝建構函式。拷貝建構函式的最常見形式如下 classname cla...
建構函式知識點
1 建構函式必須與類名相同,並且不能有返回值 返回值也不能為void 若在建構函式前面加上void,編譯器會把它認為是方法,而不是建構函式 當然在new的時候,也不能自動呼叫 2 每個類可以有多個建構函式,如果人為定義了建構函式,編譯器不會建立預設的建構函式。3 建構函式在物件例項化的時候被自動呼叫...
c 知識點 賦值運算子,構造拷貝函式
是雖然使用了 但是實際上使用物件p來建立乙個新的物件p1。也就是產生了新的物件,所以呼叫的是拷貝建構函式。首先宣告乙個物件p2,然後使用賦值運算子 將p的值複製給p2,顯然是呼叫賦值運算子,為乙個已經存在的物件賦值 說到拷貝建構函式,就不得不提深拷貝和淺拷貝。通常,預設生成的拷貝建構函式和賦值運算子...