天天看點

指派運算符函數

以下是類型CMyString的聲明,請為該類型添加指派運算符函數
class CMyString
{
public:
  CMyString(char* pData = nullptr);
  CMyString(const CMyString& str);
  ~CMyString();

private:
  char* m_pData;

};

指派運算符要注意的點如下:
(1)把傳回值的類型聲明為該類型的引用,在函數結束前傳回執行個體自身的引用(*this)。
因為隻有傳回引用,才可以允許連續指派。
(2)把傳入的參數聲明為常量引用,這樣可以避免無謂的消耗,能夠提高代碼的效率。
(3)釋放執行個體自己已有的記憶體。不可在配置設定新記憶體之前釋放自身已有的記憶體,這樣可能會造成記憶體洩露。
(4)判斷輸入的參數和目前的執行個體是不是同一個執行個體(*this)。如果是直接傳回。

初級寫法

CMyString& CMyString::operator=(const CMyString& str)
{
  if (this == &str)
    return *this;

  //釋放自身的記憶體
  delete[] m_pData;
  m_pData = nullptr;

  m_pData = new char[strlen(str.m_pData)+1];
  strcpy(m_pData, str.m_pData);

  return *this;
}

這種寫法出現的問題:
這種寫法我們是先釋放執行個體的記憶體,然後再為執行個體申請新的記憶體,那麼new的過程中可能會
出現失敗的情況。那麼m_pData将會是一個空指針的情況,CMyString不再保持有效的狀态,違背了異常安全性的原則。

進階寫法:
CMyString& CMyString::operator=(const CMyString& str)
{
  if (this != &str)
  {
    //建立一個臨時變量
    CMyString strTmp(str);

    //将指針互換
    char* pTmp = strTmp.m_pData;
    strTmp.m_pData = m_pData;
    m_pData = pTmp;
  }

  return *this;
}
      

繼續閱讀