【问题标题】:Assignment Operator Overloading in C++ Syntax ExplanationC++ 语法解释中的赋值运算符重载
【发布时间】:2018-05-28 18:48:34
【问题描述】:

我是 C++ 新手。我需要一些帮助来理解这段代码 sn-p。

Queue & operator=(const Queue &rhs)
{
    front = rhs.front;
    nWaiting = rhs.nWaiting;
    for (int i = front, j = 0; j < nWaiting; j++) 
    {
        elements[i] = rhs.elements[i];
        i = (i + 1) % 100;
    }
    return *this;
}

我无法理解为什么代码中的运算符前有一个“&”,以及它是如何与 *this 一起工作的。

我了解运算符重载。例如。下面的代码用于加法操作重载。但是我不明白为什么赋值运算符 (=) 重载需要“&”。

V3 operator* (const double factor, const V3 &b)
{
    return (b * factor);
}

【问题讨论】:

  • &表示函数的返回类型是一个Queue的引用。
  • Queue& 返回对同一对象的引用,而不是副本。目的是让= 操作改变原始对象并返回对自身的引用。
  • 请注意,此代码中的 &amp; 标记不称为运算符。运算符&amp; 获取对象的地址。但这是在声明和其他指定类型的地方使用的&amp; 的完全不同的含义。在一个类型命名另一个类型之后写&amp;,它是对刚刚命名的类型的引用。

标签: c++ reference operator-overloading this


【解决方案1】:

引用意味着避免复制对象。结果,它将返回对相同对象的引用。此外,它会提供 lvalue 作为结果。如果你仔细想想,这就是你在使用赋值运算符时想要发生的事情。

C++ 中的每个对象都可以通过this 指针访问自己的地址。

这意味着您返回对象本身。

如果您的问题是我们为什么使用*this 而不是this,那么发生这种情况是因为您需要先取消引用指针,因为返回类型是引用(而不是指针例如)。

【讨论】:

  • 在此上下文中,引用不是为了避免复制而是提供lvalue作为结果
  • @Slava 它实现了这两个目的
  • @Slava 我也应该补充一下,谢谢!现在答案改善了吗?我同意 M.M.
  • @M.M 我对此表示怀疑,假设对象非常小,通过值而不是引用传递它会更有效,那么 operator= 是否应该返回非引用?
【解决方案2】:

&amp; 表示运算符返回引用(原始对象),而不是值(对象的副本)。这避免了不必要的复制。 this 是一个指向调用操作符的对象本身的指针,所以return *this 表示返回对= 左侧对象的引用。

这允许将运算符链接起来,例如a = b = 1。这首先将 1 分配给 b,然后返回对 b 的引用。然后将b 的值分配给a。所以ab 都是1。

【讨论】:

    【解决方案3】:

    操作符没有任何返回值也可以,但是像

    那样启用链接是很常见的
    c = (a = b);
    

    这会将b 分配给a,然后将operator= 调用的返回值分配给c。由于您不想制作不必要的副本,因此您返回对对象本身的引用,即 *this。实际上避免复制并不是使用引用的唯一原因,但如果你考虑

    (d = e) = f;
    

    如果operator= 返回一个非常量 (!) 引用,这只会按预期工作(首先将e 分配给d,然后将f 分配给d)。

    注意operator* 不同,因为它不应该修改被调用的对象,而是返回一个新实例(因此在operator* 的返回中没有&amp;)。

    【讨论】:

    • “因为你不想制作不必要的副本”如果这种情况下应该使用 const 引用
    • @Slava 嗯?使用 const ref 这将不起作用:(a = b) = c;。不确定您指的是什么副本
    • 我为你的回答提供了引用,如果你的解释是正确的并且参考是用来避免不必要的复制,那么应该使用 const reference。如果还有其他原因,例如让(a = b) = c; 工作,那么您的解释是错误的。
    • @Slava const ref 如何比 non-const ref 更禁止复制?
    • 禁止复制更多?你从哪里得到的?
    猜你喜欢
    • 2013-03-30
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2015-06-01
    • 2011-01-27
    • 2011-05-31
    • 1970-01-01
    相关资源
    最近更新 更多