劍指offer 賦值運算子函式

2022-05-21 16:06:11 字數 2540 閱讀 7561

題目

如下為型別cmystring的宣告,請為該型別新增賦值運算子函式:

class

cmystring

;

思路

//

類的定義和基本形式

類其實是定義乙個特殊的資料結構,定義了類的物件包括了什麼,以及可以在這個物件上執行哪些操作

class

student;//

成員函式定義

student::student(void

)student::~student(void

)student& student::operator=(const student&other)

student* student::operator&()

const student* student::operator&() const

int student::getid(void)//

類的六大預設成員函式

建構函式:建構函式的名稱與類的名稱是完全相同的,並且不會返回任何型別,也不會返回 void

。可用於為某些成員變數設定初值(這個時候建構函式要帶引數)

析構函式:析構函式的名稱與類的名稱是完全相同的,只是在前面加了個~作為字首,它不會返回任何值,也不能帶有任何引數。

析構函式有助於在跳出程式(比如關閉檔案、釋放記憶體等)前釋放資源。在每次刪除所建立的物件時執行

拷貝建構函式:一種特殊的建構函式,其在建立物件時,是使用同一類中之前建立的物件來初始化新建立的物件

過載賦值操作符函式:對賦值操作符"=

"進行過載,解決了物件賦值的情況下,析構函式中過程中多次釋放同一塊記憶體的問題

2.賦值運算子函式又具體是啥呢?在這個函式裡面具體要實現一些什麼內容呢?

那麼通過第1點對於類的介紹,我們知道這個函式主要就是用來過載"="這個運算子,以避免使用預設賦值運算子帶來的一些麻煩。也就是自己設計乙個賦值操作來代替預設的"="來實現賦值這個操作。

自己定義賦值運算子時呢,要注意在函式結束前必須返回例項自身的引用,結合上下文也就是*this。否則返回void會導致不能連續賦值或呼叫時不能進行隱式型別轉換。

解法(劍指offer上的解法)

cmystring& cmystring::operator = (const cmystring &str)//實現的目標是把str對應的值賦給原來的物件

delete m_pdata();

//釋放原有記憶體

m_pdata=null;

m_pdata=new

char[strlen(str.m_pdata)+1];//

分配新記憶體

strcpy(m_pdata,str.m_pdata); //

通過字串複製操作,給m_pdata賦值

return *this

;}

借這裡複習一下delete的用法:

//函式原型,這並不是過載new和delete的表示式

void *operator

new(size_t); //

allocate an object

void *operator delete(void *); //

free an object

void *operator

new(size_t); //

allocate an array

void *operator delete(void *); //

free an array

解法二:之前的解法通過先釋放之前的記憶體再開闢新空間,但是如果此時記憶體不足導致new char操作丟擲異常,那麼此時m_pdata已經為空指標,再將乙個空指標通過strcpy複製給另乙個空值,容易導致程式崩潰,這樣違背了異常安全性(exception safety)的原則。

因此可以採用先分配新空間,分配成功後再釋放已有的內容。

書上給出了另乙個解法,也就是不要先對原來的值進行操作,而是類似於我們初學c語言時常用到的交換,即交換a,b等價於temp=b;b=a;a=temp

即先建立乙個臨時例項,再交換臨時例項和原來的例項。這裡的臨時例項是區域性變數,執行到if外面(即離開該變數自身的作用域),就會呼叫臨時變數的析構函式,把這一塊的記憶體給釋放掉。 

cmystring& cmystring::operator = (const cmystring &str)

return *this;

}

為什麼還需要strtemp.m_pdata=m_pdata;這一步呢?strtemp出了這個迴圈就被釋放掉了呀,那還多一步儲存m_pdata原來的值有啥意義?也就是為什麼要交換,直接賦值不就夠了嗎?

書上有一段話是:在新**中,在cmystring的建構函式中用new分配記憶體。如果由於記憶體不足丟擲諸如bad_alloc等異常,但我們還沒有修改原來例項的狀態,因此例項的狀態還是有效的,這樣就保證了異常安全性。(不知道是不是對上面疑問的解釋)

希望有大佬可以給解釋一下~~

劍指Offer 賦值運算子函式

按照自己淺薄的理解,敲了如下 include using namespace std class cmystring 就是定義了!cmystring char m pchar null cmystring const cmystring other cmystring cmystring opera...

劍指offer 賦值運算子過載

還是有很多點需要注意的。判斷this與傳入的object是否是同乙個物件,相同的話直接返回 this就可以了。判斷傳入物件的陣列是否為空,空的話就不必複製,直接釋放記憶體並將指標置null即可。考慮異常安全。因為new char時如果記憶體不足會丟擲異常,這時安全的做法是先嘗試申請記憶體,申請成功後...

劍指offer1 賦值運算子函式

include using namespace std class cmystring cmystring const cmystring str cmystring operator const cmystring str int display cmystring private char m ...