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)