[剑指offer]面试题1:赋值运算符函数
面試題1:賦值運算符函數
題目:如下為類型CMyString的聲明,請為該類型添加賦值運算符函數。
經典解法,適用初級程序員:
CMyString & CMyString::operator=(const CMyString &str) {if (this == &str) return *this;delete[] m_pDate;m_pDate = nullptr;m_pDate = new char[strlen(str.m_pDate) + 1];strcpy(m_pDate, str.m_pDate);return *this; }在前面的函數中,我們在分配內存之前先用delete釋放了實例m_pData的內存。如果此時內存不足導致new char拋出異常,m_pData將是一個空指針,這樣非常容易導致程序崩潰。也就是說一旦在賦值運算符函數內部拋出一個異常,CMyString的實例不再保持有效的狀態,這就違背了異常安全性(Exception Safety)原則。
(通俗來說,就是我們new空間的時候,如果此時內存不足,就new不出來,編譯器就會報錯,可這個時候我們原來的CMyString的m_pDate被我們釋放了)
解決方法一:
我們先用new分配新內容再用delete釋放已有的內容。這樣只在分配內容成功之后再釋放原來的內容,也就是當分配內存失敗時我們能確保 CMyString 的實例不會被修改。
解決方法二(更好):
先創建一個臨時實例,再交換臨時實例和原來的實例。
解法二代碼如下:
CMyString & CMyString::operator=(const CMyString &str) {if (this != &str){CMyString strTemp(str);char *pTemp = strTemp.m_pDate;strTemp.m_pDate = m_pDate;m_pDate = pTemp;}return *this; }在這個函數中,我們先創建一個臨時實例 strTemp,接著把strTemp.m_pData和實例自身的m_pData做交換。
由于strTemp是一個局部變量,但程序運行到 if 的外面時也就出了該變量的作用域,就會自動調用strTemp 的析構函數,把 strTemp.m_pData 所指向的內存釋放掉。
由于strTemp.m_pData指向的內存就是實例之前m_pData的內存,這就相當于自動調用析構函數釋放實例的內存。
在新的代碼中,我們在CMyString的構造函數里用new分配內存。
如果由于內存不足拋出諸如bad_alloc等異常,我們還沒有修改原來實例的狀態,因此實例的狀態還是有效的,這也就保證了異常安全性。
測試用例:
● 把一個CMyString的實例賦值給另外一個實例。
● 把一個CMyString的實例賦值給它自己。
● 連續賦值。
本題考點:
● 考查對C++的基礎語法的理解,如運算符函數、常量引用等。
● 考查對內存泄露的理解。
● 對高級C++程序員,面試官還將考查應聘者對代碼異常安全性的理解。
總結
以上是生活随笔為你收集整理的[剑指offer]面试题1:赋值运算符函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何获得抖音神秘人套装
- 下一篇: 怎么把腾讯视频的qlv格式转换为mp4格