0

因此,我爲整數創建一個容器類,並且我想重載=運算符,以便我可以返回對象的深層副本。我的代碼工作但兩個對象指向相同的地址。這是的main.cpp文件:重載=運算符時返回對象的深層副本

int main (int argc, const char * argv[]) { 
    IntList cArray(5); 

    for (int i = 0; i < cArray.getLength(); i++) { 
     cArray[i] = (i + 1) * 10; 
    } 

    using namespace std; 

    for (int i = 0; i < cArray.getLength(); i++) 
     cout << cArray[i] << " "; 
    cout << endl << popped << endl; 

    IntList cArray2(4); 

    for (int i = 0; i < cArray2.getLength(); i++) 
     cArray2[i] = i * 5; 

    cArray2 = cArray; 
    cArray2[2] = 1000; 

    for (int i = 0; i < cArray.getLength(); i++) 
     cout << cArray[i] << " "; 
    cout << endl; 
    for (int i = 0; i < cArray2.getLength(); i++) 
     cout << cArray2[i] << " "; 
    cout << endl; 

    return 0; 
} 

這是IntList類的頭文件:

class IntList { 
private: 
    int _length; 
    int* _data; 

public: 
    IntList(int length); 
    ~IntList(); 

    void erase(); 
    void reallocate(int length); // Faster way to call erase() and resize() 
    void resize(int length); 
    void insert(int value, int index); 
    void prepend(int value); 
    void append(int value); 
    int pop(int index); 
    void removeBefore(int index); // Exclusive 
    void removeAfter(int index); // Exclusive 
    int getLength(); 
    int indexOf(int value); 

    int& operator[](int index); 
    IntList operator=(IntList* source); 
}; 

這是實施IntClassoperator=()方法:

IntList IntList::operator=(IntList* source) { 
    _length = source->getLength(); 

    reallocate(_length); 

    for (int i = 0; i < _length; i++) { 
     _data[i] = (*source)[i]; 
    } 

    return *this; 
} 
+0

問題必須以初始化'_data'的方式進行,但您沒有向我們展示該部分。 – 2011-03-25 19:05:15

+0

@Mark,'IntList :: IntList(int length):_data(new int [length]),_length(length)' – 2011-03-25 19:10:09

回答

2

您沒有使用指向IntList的指針 - operator=通常需要const &並返回是對被分配的實例的引用。

IntList & IntList::operator=(IntList const & source) { 
    ... 
    return *this; 
} 

請記住,你還需要一個拷貝構造函數:IntList(IntList const & source)

可以使運營商=這需要一個指向intList中 - 如果你做了這樣的事情,只會工作:

IntList l1; 
IntList l2; 
l1 = &l2; 

這不是典型的用法,如果你需要這個,你應該更加明確,使用eg在這種情況下爲void IntList::copyFrom(IntList const *)

其他的變化,你應該:

補充一點:

int operator[](int index) const; 

讓這些常量:

int getLength() const; 
int indexOf(int value) const; 
+0

請參閱我對Mark的回答的評論。 – 2011-03-25 19:07:24

+0

@Tyler:您需要使getLength爲const,並添加一個const運算符[] - 請參閱已更新的答案 – Erik 2011-03-25 19:13:45

+0

謝謝。這工作。我沒有正確地將我的函數標記爲const。 – 2011-03-25 19:22:08

1

你的運營商是否需要簽名IntList& operator=(const IntList& source);。請注意引用而不是指針,並且您必須通過引用返回以允許分配鏈接。當你在需要隱式賦值的地方通過指針傳遞它時,編譯器生成的淺拷貝賦值操作符將被使用。

編輯:您還需要使getLengthconst,以便它可以在賦值運算符內部調用。

+0

我只是試過你的建議,我意識到我忘記將'IntList :: getLength()'標記爲const。但現在Xcode告訴我「錯誤:語義問題:成員函數'getLength'不可行:'this'參數的類型'const IntList',但函數沒有標記爲const」。 – 2011-03-25 19:07:04

1
IntList IntList::operator=(IntList* source) 

operator=簽名錯誤,因爲它的參數類型是指針IntList

正確的簽名是這樣的:

IntList & IntList::operator=(const IntList & source) //reference of source! 
    //^^^ note this      ^^^ note this as well! 

也就是說,使這兩個參數作爲返回類型,以及型號參考

+1

好點,但是不會拒絕用原始簽名編譯代碼嗎? – 2011-03-25 19:07:51

+1

@Mark Ransom舊代碼是完全有效的,編譯器爲你高興地生成一個默認的淺拷貝賦值運算符。 – 2011-03-25 19:09:46

+0

@Mark Ransom:不。在我看來,這只是另一個重載,您必須通過編寫'intlist2.operator =(&intlist)'明確調用它。它不會通過編寫'intlist2 = intlist1'來調用。 – Nawaz 2011-03-25 19:11:21

2

因爲你的賦值運算符需要一個指向intList中,你需要調用它像這樣:

cArray2 = &cArray; 

您的示例代碼使用你的編譯器生成的默認賦值運算符。您的作業操作員應該使用以下聲明:

IntList& IntList::operator=(IntList const& source)