拷貝建構函式和過載賦值操作符(以共享指標為例子)

2021-10-08 00:05:05 字數 2218 閱讀 2962

//呼叫了拷貝建構函式的話,對應的指標變數 的值++;

sharedpointer(const sharedpointer& obj) :pointer(null) //這裡也應該呼叫父類拷貝建構函式?

//賦值本質上是沒有增加指標變數的值 因為clear了(換句話---拷貝建構函式大多數情況下是複製,而賦值函式是引用物件)

//引用知識別名,所以本質上沒有增加

sharedpointer& operator= (const sharedpointer& obj)

return *this;

}

淺拷貝只是簡單地對變數進行賦值,而對指標變數進行簡單賦值只是將位址賦給新物件的指標變數,這樣兩個物件的指標變數指向同一塊記憶體空間。這樣根據析構函式的析構順序,新物件析構掉的時候將記憶體釋放了,就物件析構的時候就會導致記憶體訪問出錯。因此,自定義拷貝建構函式是一種良好的程式設計風格,它可以阻止編譯器形成預設的拷貝建構函式(這段話介紹一下 為什麼要深拷貝!)

拷貝構造就是:用乙個已初始化過了的自定義類型別物件去初始化另乙個新構造的物件的時候,網上找到乙個例子

在面物件程式設計中,物件間的相互拷貝和賦值是經常進行的操作。

如果物件在申明的同時馬上進行的初始化操作,則稱之為拷貝運算。例如:

class1 a("af"); class1 b=a;

此時其實際呼叫的是b(a)這樣的淺拷貝操作。

如果物件在申明之後,在進行的賦值運算,我們稱之為賦值運算。例如:

class1 a("af"); class1 b;

b=a;

這樣就回答了 拷貝構造和賦值的區別啦!

可以看到 構造函式呼叫的話 計數+1,而賦值卻不會,因為賦值會清空=左邊物件的狀態 在賦值 ;

一般輸入的引數 是以const 修飾的:

1.加const是因為:

①我們不希望在這個函式中對用來進行賦值的「原版」做任何修改。

②加上const,對於const的和非const的實參,函式就能接受;如果不加,就只能接受非const的實參。

用引用是因為:這樣可以避免在函式呼叫時對實參的一次拷貝,提高了效率。

2.一般地返回值是被賦值者的引用,即*this,原因是

①這樣在函式返回時避免一次拷貝,提高了效率。

②這樣可以實現連續賦值,即類似a=b=c這樣。如果不是返回引用而是返回值型別,那麼,執行a=b時,呼叫賦值運算子過載函式,在函式返回時,由於返回的是值型別,所以要對return後邊的「東西」進行一次拷貝,得到乙個未命名的副本(有些資料上稱之為「匿名物件」),然後將這個副本返回,而這個副本是右值,所以,執行a=b後,得到的是乙個右值,再執行=c就會出錯。

(可以看到引用在避免初始化 + 避免呼叫運算子過載 有很好的效果)

3.賦值運算子過載函式只能是類的非靜態的成員函式

c++規定,賦值運算子過載函式只能是類的非靜態的成員函式,不能是靜態成員函式,也不能是友元函式。之所以不是靜態成員函式,是因為靜態成員函式只能操作類的靜態成員,不能操作非靜態成員。如果我們將賦值運算子過載函式定義為靜態成員函式,那麼,該函式將無法操作類的非靜態成員,這顯然是不可行的。為了避免這樣的二義性,c++強制規定,賦值運算子過載函式只能定義為類的成員函式。

4.賦值運算子過載函式不能被繼承

相較於基類,派生類往往要新增一些自己的資料成員和成員函式,如果允許派生類繼承基類的賦值運算子過載函式,那麼,在派生類不提供自己的賦值運算子過載函式時,就只能呼叫基類的,但基類版本只能處理基類的資料成員,在這種情況下,派生類自己的資料成員怎麼辦?所以,c++規定,賦值運算子過載函式不能被繼承。

5.賦值運算子過載函式要避免自賦值

對於賦值運算子過載函式,我們要避免自賦值情況(即自己給自己賦值)的發生,一般地,我們通過比較賦值者與被賦值者的位址是否相同來判斷兩者是否是同一對。

既然看到了拷貝構造,再繼續複習複習:

1.什麼時候會呼叫拷貝建構函式呢?

在c++中,下面三種物件需要呼叫拷貝建構函式(有時也稱「複製建構函式」):

1) 乙個物件作為函式引數,以值傳遞的方式傳入函式體;

2) 乙個物件作為函式返回值,以值傳遞的方式從函式返回;

3) 乙個物件用於給另外乙個物件進行初始化(常稱為複製初始化);

拷貝建構函式和賦值操作符

類有預設的建構函式 拷貝建構函式 析構函式 賦值操作運算子 和取位址運算子 預設的賦值操作運算子和預設的拷貝建構函式類似,對於每個非static成員,都是執行逐個成員賦值 memberwise assignment 同時也是按位賦值 bitwise copy 即,只是簡單地將每個類成員的記憶體中的直...

賦值操作符和拷貝建構函式

最近開發乙個專案,用到了單例模式,標頭檔案大概如下 class crecguard crecguard private void guard void unguard private critical section cs template class csingleton 禁止建構函式 csing...

C 中的拷貝建構函式和賦值操作符過載

在c 中,當乙個類為 空 時,裡面真的為空嗎?不是的,裡面有四個函式。分別是建構函式,析構函式,拷貝建構函式,過載賦值操作符。class test 等價於class test 拷貝建構函式和過載賦值操作符有什麼區別?test t1 test t2 t1 等價於test t2 t1,此時呼叫拷貝建構函...