1. 程式人生 > 實用技巧 >C++的過載賦值運算子

C++的過載賦值運算子

我們在定義類的時候編譯器會自動建立對賦值運算子的過載,但類似拷貝建構函式,這個過載函式也只是對值的拷貝,如果類中有在堆區開闢的空間則需要實現深拷貝。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 //定義型別CMyString
 5 class CMyString
 6 {
 7 public:
 8     CMyString(char* pData = nullptr);
 9     
10     //過載賦值運算子
11     CMyString& operator=(const CMyString &str);
12 13 ~CMyString(void); 14 15 private: 16 char* m_pData; 17 }; 18 19 CMyString::CMyString(char* pData = nullptr) 20 { 21 int len = strlen(pData); 22 this->m_pData = (char*)malloc(sizeof(char)*(len + 1)); 23 memset(m_pData, '\0', sizeof(char)*(len + 1)); //將\0賦值給m_pData,長度為第三個引數大小
24 strcpy(m_pData, pData); 25 } 26 27 28 //過載賦值運算子 29 //為實現鏈式賦值,返回值需要是本身,另外為減少拷貝構造,返回的為CMyString& 30 CMyString& CMyString::operator=(const CMyString &str) 31 { 32 //如果賦值的兩個物件是同一個,則不能賦值 33 if (&str == this) 34 return *this; 35 36 //從堆區開闢新的空間時,首先釋放之前的空間 37 if (this
->m_pData != NULL) 38 { 39 delete[] this->m_pData; 40 this->m_pData = NULL; 41 } 42 43 //從堆區開闢新的空間 44 this->m_pData = new char[strlen(str.m_pData)+1]; 45 strcpy(m_pData, str.m_pData); 46 47 //返回自身 48 return *this; 49 } 50 51 CMyString::~CMyString(void) 52 { 53 if (this->m_pData != NULL) 54 { 55 delete this->m_pData; 56 this->m_pData = NULL; 57 } 58 }

過載賦值運算子時主要需要考慮下面幾點:

  • 為了實現鏈式賦值操作,函式的返回值應該是其自身,另外為了節省拷貝構造的花銷,返回值型別應該是其自身的應用,在上面案例中為CString&;
  • 為防止引數在過載函式中發生變化,傳入的引數型別應該是常量引用;
  • 在申請堆區空間之前應該考慮是否需要先釋放自身之前在堆區所佔用的空間;
  • 在實現深拷貝之前首先應該判斷賦值的兩個物件是不是相同的,如果是相同的應該直接返回。若沒有考慮到相同的情況,那麼在釋放自身空間的時候會出現問題,即已經被釋放的空間再次被拿來賦值自身;
  • 返回值應該是*this.