重载操作符=

overloading operator =

本文关键字:操作符 重载      更新时间:2023-10-16

我必须创建一个函数,该函数重载=操作符,以便当您放入object1 = object2;时,它会将object2中的所有值复制到object1中。

我的类是这样的:

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

我的重载函数声明为:

foo& foo::operator=(const foo& matrix);
foo::foo(std::istream& s);  //constructor

我该怎么做呢?

最好的方法是使用复制和交换习惯用法。
另外,请注意,如果您觉得需要重载复制赋值操作符,那么您可能还需要重载复制构造函数以及析构函数

一定要看看三法则

简单地复制所有值是编译器提供的复制构造函数的默认行为。这就是所谓的"浅拷贝"。

通过实现您自己的构造函数来实现更精细的行为,以便在副本中重新创建引用所指向的对象(这里是值)。

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];
}

Ravi,是的,复制构造函数是构造的证明,尽管打破了"三法则",但它可以在其他两个之前实现。这是赋值操作符。

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);
};

当然,它需要一个析构函数,但由于没有明确要求它,所以我不想回答没有被要求的问题。

在链接到复制和交换习惯用法之后,当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;
    }
}

我想补充一点,在堆上分配局部对象可能会导致内存泄漏(如果方法在将它们分配给负责删除它们的对象之前中断),但是当我们有足够的工作来保持类完整性时,这只是另一层偏执。

在google上搜索" c++赋值运算符"就能找到这个有用的网站;-)