16

说我想覆盖,operator =所以我可以做类似的事情

Poly p1;  // an object representing a polynomial
Poly p2;  // another object of the same type    
p2 = p1;  // assigns all the contents of p1 to p2

然后在我的实现中operator =,我有这样的事情:

Poly& Poly::operator=(const Poly &source) {
    // Skipping implementation, it already works fine…
    return *this;
}

不要介意实施,它已经可以正常工作了。

我担心的是,当你发生了什么return *this?我知道它返回对对象的引用,但这是怎么回事?

p2 = &p1
4

5 回答 5

26

这样您return *this就可以编写普通的复合 C++=语句,例如:

Poly p1; //an object representing a polynomial
Poly p2;
Poly p2;

// ...

p3 = p2 = p1;  //assigns all the contents of p1 to p2 and then to p3

因为该声明基本上是:

p3.operator=(p2.operator=(p1));

如果p2.operator=(...)不是return *this,您将没有任何有意义的东西可以传递给p3.operator=(...).

于 2016-01-02T05:22:34.417 回答
10

p2 = p1是 的简写p2.operator=(p1)。它只是调用您的operator=函数,该函数返回对 的引用p2,然后您将忽略该引用。为了清楚起见,让我们调用它assign而不是operator=

Poly& Poly::assign(const Poly &source) {
    .
    .
    .
    return *this;
}

现在代替p2 = p1, 你会写

p2.assign(p1);

在这种情况下,调用的结果将assign被忽略,但您不必忽略它。例如,您可以编写:

p3.assign(p2.assign(p1));

使用operator=代替assign,这变成

p3 = (p2 = p1);

但由于赋值是右结合的,这也可以写成

p3 = p2 = p1;

这种能够一次执行多个赋值的形式最初来自 C,并且通过返回*thisin的约定保留在 C++ 中operator=()

于 2016-01-02T05:28:15.903 回答
7

void如果您无论如何都不需要链式分配(如其他答案所示),可能会试图让复制分配运算符返回。毕竟,链式作业通常很难阅读和理解,因此不允许它们可能被认为是一种改进

但是,一个经常被忽视的方面是这void operator=(Poly& const)意味着您的类型将不再满足需要返回类型的CopyAssignable概念。T&

一个不符合这个CopyAssignable概念的类型不能正式用于某些标准容器操作,例如std::vector::insert,这意味着以下看似无辜的代码会产生未定义的行为,即使它可能运行得很好:

#include <vector>

struct Poly
{
    void operator=(Poly const&) {} // Poly is not CopyAssignable
};

int main()
{
  std::vector<Poly> v;
  Poly p;
  v.insert(v.begin(), p); // undefined behaviour
}

正如 C++ 标准在 § 17.6.4.8/2.3 中解释的那样,它讨论了使用标准库的程序的约束:

(...)在以下情况下效果未定义:

(...) 对于在实例化模板组件时用作模板参数的类型,如果对该类型的操作未实现适用的要求子条款 (...) 的语义。

当然,正是由于未定义的行为,编译器才被允许忽略错误并使程序表现良好,与明显预期的行为相匹配。但这不是必须的。

您还应该考虑到您无法预测您的Poly类型的所有未来用途。有人可能会编写一些模板函数,例如:

template <class T>
void f(T const& t)
{
    T t2;
    T t3 = t2 = t;
    // ...
}

然后,此功能将不适用于您的Poly班级。

只要不违反这个 C++ 约定,你就不会遇到麻烦。

于 2016-01-02T13:02:10.630 回答
3

返回 *this 时会发生什么?

在您的示例(p2 = p1;)中,什么都没有。该方法复制p1p2返回对“this”对象的引用,调用代码不使用该对象。

在诸如此类的代码中p3 = p2 = p1;,第一个调用是p2 = p1,它复制p1p2返回对 的引用p2。然后调用代码从该引用复制p2到其中p3(并忽略对p3返回的引用)。

(顺便说一句:您的单元测试是否确保其p1 = p1正常工作?很容易忘记这种情况!)

于 2016-01-07T17:52:52.590 回答
0

返回对目标对象的引用允许赋值链接(级联),并且类中的重载运算符遵循右关联(单击此处查看详细的运算符重载规则)

Poly a, b, c;
a = b = c;
于 2016-01-02T05:38:28.257 回答