2011-08-30 161 views
0

我要創建哪些重載=操作,這樣,當你把object1 = object2;它會在所有的值複製內部對象2到object1的功能。重載運算符=

我班的樣子:

class foo { 
    private: 
    int max; 
    int *val; 
    size_t *listofVal; 
} 

我的過載函數聲明爲:

foo& foo::operator=(const foo& matrix); 

foo::foo(std::istream& s); //constructor 

我會怎麼做呢?

+2

這看起來像作業。你已經嘗試了什麼? –

+0

@sasha我已經嘗試過讓'private'變量'mutable',但我認爲這相當難看。 – SNpn

+0

SNpn:您的重載操作符是您的'foo'類的成員,因此可以訪問私有成員數據。 – razlebe

回答

-1

谷歌搜索「C++賦值運算符」給你this useful site ;-)

+5

鏈接通常不被視爲SO上的好答案。 –

+0

我認爲這不是一個有用的答案,你可以在網上找到很多「壞老師」。這就是爲什麼人們在這個網站上發佈問題的原因 –

+0

我認爲自己研究這個主題(不一定在互聯網上,但也在書本上)是可能的,這就是爲什麼我只是發佈了一個鏈接。我想我將來不會這樣做。 –

1

簡單地複製所有的值時,編譯器提供複製構造器的默認行爲。這被稱爲「淺拷貝」。

更復雜的行爲是通過實現自己的構造函數來實現的,以便您的引用指向的對象(這裏是值)在副本中重新創建。

foo::foo(std::istream& s) { 
    max = s.max; 
    val = new int; 
    *val = s->val; 
    listofVal = new size_t; 
    *listofVal = s->listofVal; 
} 

將是實現被稱爲「深度複製」的一種方式。

但是,作爲你的一個成員被稱爲listofVal我寧願覺得你正在做的事情不是在它指向的內存地址上存儲單個值,在這種情況下,你應該對其中包含的元素數進行計數,我將從此以後假設爲您稱爲max的字段。要複製整個列表,你的拷貝構造函數,然後必須是:

foo::foo(std::istream& s) { 
    max = s.max; 
    val = new int; 
    *val = s->val; 
    listofVal = new size_t[max]; 
    for (int i = 0; i < max; ++i) 
     listofVal[i] = s->listofVal[i]; 
} 

拉維,是的,拷貝構造函數是構建的,儘管打破了「規則三」的證明可以在另一個之前實現兩個。這是賦值運算符。

foo& foo::operator=(const foo& matrix) { 
    if (this != matrix) { 
     max = matrix.max; 
     val = new int; 
     *val = matrix->val; 
     listofVal = new size_t[max]; 
     for (int i = 0; i < max; ++i) 
      listofVal[i] = matrix->listofVal[i]; 
    } 
} 

將適用於object1 = object2;作業。我傾向於複製構造函數的方法。

的方法必須是會員訪問私人數據,以便類應該像

class foo { 
    ///...///As before 
    foo &operator=(const foo& matrix); 
}; 

當然它需要一個析構函數,但因爲它沒有明確要求,我不想回答什麼WASN我問道。

從鏈接複製和交換成語,當LHS可能已經包含數據,強大的任務之後你可能會考慮:

foo& foo::operator=(const foo& matrix) { 
    if (this != matrix) { 
     val = new int; 
     *val = matrix->val; 
     size_t* newArray = new size_t[max]; 
     int newMax = matrix.max; 
     std::copy(matrix.listofVal, matrix.listofVal + max, newArray); 
     if (listofVal) delete listofVal; 
     listofVal = newArray; 
     max = newMax; 
    } 
} 

我想補充一點,在堆中分配的本地對象可引起內存泄漏(如果方法在它們被分配給負責刪除的對象之前中斷),但是當我們有足夠的時間來保持類的完整性時,這只是一個完整的黑暗層。

+1

我想你的意思是定義'foo&foo :: operator =(const foo&matrix)' – bluefalcon

+0

@John即使它們是私人的,我們是否允許這樣做? – SNpn

+0

此外,如果在foo ctor中爲它們分配內存,則必須照顧指針。如果是這樣,你必須包括檢查自我分配以避免內存損壞,否則內存將被釋放兩次。 – Riga

5

要做到這一點的最佳方法是使用Copy and Swap成語。
另請注意,如果你覺得超載拷貝賦值運算符的需要,那麼你也可能需要重載拷貝構造函數以及爲您的課析構函數

看看Rule of Three

+0

請注意,複製和交換將爲您提供強大的例外安全保證,您可能不需要。默認情況下使用CAS,但如果遇到(性能問題)性能問題,則考慮實施只有弱保證的賦值運算符。 – Mankarse

+0

@Mankarse:你爲什麼認爲複製和交換不是最優的? –

+0

@Martin,因爲複製和交換意味着對象中的每個基元都必須被複制到一個臨時對象中,然後從該臨時對象分配給受讓者。對於不擁有許多外部資源的大對象,這可能會很慢。您也失去重用受讓人已經分配的內存的機會。我認爲大多數程序不會因爲這些事情而顯着減慢,但值得知道的是,這裏有複製和交換的正確選擇。 – Mankarse