2012-04-28 237 views
0

請幫助完成賦值重載函數的執行。賦值=運算符超載

這裏是指令:

賦值運算符(=),這將源字符串複製到目標字符串。請注意,目標的大小需要調整爲與來源相同。

加法(+)和賦值(=)操作符都需要能夠級聯操作。這意味着String3 = String1 + String2String1 = String2 = String3應該工作。

這裏是我的.cpp文件:

int MyString::Length() 
{ 
     int counter(0); 

     while(String[counter] != '\0') 
     { 
      counter ++; 
     } 
    return (counter); 
} 

MyString& MyString::operator=(const MyString& rhs) 
{ 

     if(this != &rhs) 
     { 

       delete [] String; 
       String = new char[rhs.Length()]; 

      for(int i = 0; i <rhs.Length()+1 ; i++) 
      {  
        String[i] = rhs.String[i]; 
      }  


     } 
     return *this; 

} 

這就是所謂的通過的main.cpp文件:

的String1 = String2的= STRING3;

我覺得好像我失去了一些東西。幫助!

+2

在例外的臉想想正確性! – dirkgently 2012-04-28 21:21:12

+0

具體問題是什麼? – 2012-04-28 21:22:20

+3

您正在保留'this-> Size'字符,您正在複製'this-> counter'字符。不應該是'rhs.Size'或'rhs.counter'? – 2012-04-28 21:25:17

回答

2

我想Stringchar*。也許那麼,Size,這是新的長度,需要設置爲rhs的長度,這是新的字符串。所以它應該是rhs.Size,而不是這個 - >大小,這可能是這種情況。請注意,終止空字符也應該在char數組大小中考慮。

之後,您可以輸入循環,再次照顧所有的字符,並終止空字符。鑑於我們不知道counter是什麼,並假設它是沒有空字符的新字符串長度(因此+ 1會計),我想這個循環沒有任何問題。

+0

所以當我說String = new char [Size.Length()]這是你的意思嗎?或者應該像這樣聲明,Size = rhs.Size;是的,我瘋狂的循環,但我已經編輯它。 – user1363061 2012-04-28 22:02:27

+0

'delete [] String'後,應該這樣做:'Size = rhs.Size'。在完成之後,新的'String'應該是'String = new char [rhs.Size]',或者只是'String = new char [Size]',因爲'Size'現在等於'rhs.Size' 。如果Size忽略終止字符,請添加一個。這裏的要點是你需要使任何成員變量等於作爲參數傳遞給賦值運算符的對象。 – 2012-04-28 22:07:55

+1

很高興知道你錯了什麼。但最後你必須使用複製和交換(或者解決如何以異常安全的方式編寫它)。複製和交換成語也只有三行,所以一旦你知道它,寫起來也更容易。 – 2012-04-28 22:16:30

4

結帳copy and swap idiom

您的代碼存在的問題之一是它不是異常安全的。
它甚至不符合basic exception guarantee

如果在新操作過程中拋出,則對象將處於完全無法使用的狀態。如果事實處於危險狀態,因爲如果在堆棧展開期間因爲異常而調用析構函數,您將得到未定義的行爲,因爲析構函數將再次調用String上的刪除。

的對象上的所有方法,應該在三個階段行動:

  1. 盡一切可以拋出,但不改變對象的工作。
    • 所以,如果你拋出物體保持良好的狀態。
  2. 將您在(1)中創建的數據以異常安全的方式與對象數據進行交換。
    • 這就是爲什麼swap()方法是無拋出
  3. 整理好,並刪除。
    • 由於對象再次處於一致狀態,可以拋出哪個對象。

複製和交換成語封裝了這些步驟,而在很好的易於使用的技術。

+0

「整潔和刪除」不應該需要完成,因爲在C++中我們使用智能指針。 (你是吧?) – 2012-04-28 21:56:33

+0

這是正確的 – user1363061 2012-04-28 22:00:08

+0

@MooingDuck:智能指針是一種實現技術。這些原則仍然存在,有一個整潔和階段。另外String實際上是一個容器,因此智能指針並不適用。智能指針和容器是不同但適用於內存管理的並行技術。 – 2012-04-29 09:13:16

1

在開始賦值運算符重載之前,讓我們看看運算符在C++中的重載。在面向對象編程中,運算符重載 - 通常稱爲運算符ad hoc多態 - 是多態的一個特例,其中不同的運算符根據它們的參數有不同的實現。運算符重載一般由語言,程序員或兩者來定義。使用操作符重載是因爲它允許開發人員使用更接近目標域的符號進行編程,並允許用戶定義的類型與內置於語言中的類型具有類似的語法支持級別。例如,在科學計算中很常見,它允許用與紙上相同的語法來操作數學對象的計算表示。可以使用函數調用來模擬對象重載。

我們現在該怎麼重載賦值運算符(=),

我們這樣做賦值運算符重載後,我們隨後將能夠分配我們的自定義數據類型的兩個變量。讓我們來看看下面的例子:

// Operator overloading in C++ 
//assignment operator overloading 
#include<iostream> 
using namespace std; 

class Employee 
{ 
private: 
int idNum; 
double salary; 
public: 
Employee () { 
    idNum = 0, salary = 0.0; 
} 

void setValues (int a, int b); 
void operator= (Employee &emp); 

}; 

void Employee::setValues (int idN , int sal) 
{ 

salary = sal; idNum = idN; 

} 

void Employee::operator = (Employee &emp) // Assignment operator overloading function 
{ 
salary = emp.salary; 
} 

int main () 
{ 

Employee emp1; 
emp1.setValues(10,33); 
Employee emp2; 
emp2 = emp1;  // emp2 is calling object using assignment operator 

} 

現在讓我們來解釋一下這個代碼重載「=」操作符,我們使用功能「setValues方法」,這是一個分配的值,以「國際化域名」和「SAL」 「Employee」類的公共成員函數,現在我們的重點是定義爲「operator =」的重載函數。在這個函數中,我們將薪水的值分配給同一個類的另一個變量,這樣我們就可以直接在我們的main()函數中使用賦值操作符。現在,您可以在main()中看到,我們有兩個變量emp1和emp2,類型爲Employee,我們可以直接在最後一行代碼中使用賦值運算符,這全是因爲運算符「=」的賦值運算符重載或運算符重載。 」。