對於許多重要的實用類來說,僅有預設的賦值運算子函式是不夠的,還需要使用者根據實際需要自己對賦值運算子進行過載,已解決遇到的問題。指標懸掛就是這方面的乙個典型問題。在某些特殊情況下,如類中有指標型別時,使用預設的賦值運算子函式會產生錯誤。例如,
例 1:關於淺層賦值的例子。
#include
#include
using
namespace std;
class
string
~string()
};intmain()
執行結果:
(1)程式開始執行,建立物件 p1 和 p2 ,分別呼叫建構函式,通過運算子 new 分別從記憶體中動態分配一塊空間,字元指標 ptr 指向記憶體空間,這時兩個動態空間中的字串分別為 「book」和「jeep」。
(2)執行語句「p2=p1;」 時,因為沒有使用者自定義的賦值運算子函式,於是呼叫預設的賦值運算子函式,使兩個物件 p1 和 p2 的指標 ptr 都指向 new 開闢的同乙個空間,這個動態空間中字串為「book」。
(3)主程式結束,物件逐個撤銷。先撤銷物件 p2,第 1 次呼叫析構函式,儘管這時 p1 的指標 ptr 存在,但是其所指向的空間卻無法訪問了,出現了所謂的 「指標懸掛」,輸出出現異常。由於第 2 次執行析構函式中語句「 delete ptr; 」時,企圖釋放同一空間,從而導致了對同一記憶體空間的兩次釋放,這必然引起執行錯誤。
執行 p2=p1 之前:
執行 p2=p1 之後:
撤銷物件 p2 後:
為了解決淺層複製出現的錯誤,必須顯式地定義乙個自己的賦值運算子,使之不但賦值資料成員,而且為物件 p1 和 p2 分配了各自的記憶體空間,這就是深層複製。
例 2 是在例 1 的基礎上,增加了乙個自定義的賦值運算子過載函式。
例 2:關於深層複製的例子。
#include
#include
using
namespace std;
class
string
~string()
string &
operator=(
const string &);
//宣告賦值運算子過載函式 屬於成員運算子過載函式
//string &operator屬於使用引用返回函式值,返回函式的值型別為 string
//const string & 屬於使用常引用作為函式引數 學習筆記30 };
string &string::
operator=(
const string &s)
intmain()
執行結果:
(1)建立物件 p1 和 p2,分別呼叫建構函式,通過運算子 new 分別從記憶體中動態分配一塊空間,字元指標 ptr 指向記憶體空間,這兩個動態空間中的字串分別為「book」和「jeep」。
(2)執行語句「p2=p1」時,呼叫自定義的賦值運算子過載函式,釋放掉了 p2 指標 ptr 所指的舊區域,又按照新長度分配新的記憶體空間給 p2,再把物件 p1 的資料成員賦給 p2 的對應的資料成員中。
(3)主程式結束,物件逐個撤銷。
執行 p2=p1 之前:
執行 p2=p1 之後:
撤銷物件 p2 後:
注意:
類的賦值運算子 「=」 只能過載為成員函式,而不能把它過載為友元函式,因為如果過載為友元函式:
friend string &
operator
=(string &p2,string &p1)
;
表示式 p1=「book」 將被解釋為:
operator
=(p1,
"book"
);
這沒有問題。但是對於表示式 「book」=p1 將被解釋為:
operator=(
"book"
,p1)
;
即 c++ 編譯器首先將 「book」 轉換成乙個隱藏的 string 物件,然後使用物件 p2 引用該隱藏物件,編譯器並不認為這個表示式是錯誤的,從而將導致賦值語句上的混亂。因此雙目賦值運算子應過載為成員函式的形式,而不能過載為友元函式的形式。 運算子過載 賦值運算子的過載
有時候希望賦值運算子兩邊的型別可以不匹配,比如,把乙個int型別變數賦值給乙個complex物件,或把乙個 char 型別的字串賦值給乙個字串物件,此時就需要過載賦值運算子 注意 賦值運算子 只能過載為成員函式 賦值運算子過載例項示例 include include using namespace ...
運算子過載 類的賦值運算子過載
下面介紹類的賦值運算子 1.c 中物件的記憶體分配方式 在c 中,物件的例項在編譯的時候,就需要為其分配記憶體大小,因此,系統都是在stack上為其分配記憶體的。這一點和c 完全不同!千 萬記住 在c 中,所有類都是reference type,要建立類的實體,必須通過new在heap上為其分配空間...
過載賦值運算子
1 注意過載賦值運算子和,運算子必須定義為類的成員函式。2 注意 如果程式不提供顯示的賦值運算子則系統會提供乙個預設的賦值運算子。3 什麼時候過載賦值運算子 當類中含有指標成員時,一般都要重定義類的賦值運算子。4 過載賦值運算子時應有處理語句m m的情況。其中m是某乙個類的物件。如果不處理這樣的語句...