【问题标题】:Why I can't define operator= with non-reference return type?为什么我不能用非引用返回类型定义 operator=?
【发布时间】:2011-08-31 08:29:30
【问题描述】:

类中的 C++ 中的 Operator= 声明如下:

 MyType & operator=(const MyType & rhs);

原因是链接是必要的。但是,由于 operator= 具有正确的优先级,因此返回值就足够了。

【问题讨论】:

  • 问题写在question-title中:Why I can't define operator= with non-reference return type?
  • @George:问题标题是个问题……

标签: c++ operators operator-overloading operator-precedence


【解决方案1】:

如果你不按引用返回,你就是按值返回,你不能赋值给一个值,因为只有左值是可赋值的。即使可以,也没关系,因为您分配给它的对象会在您分配给它后很快被销毁,因为它只是对象的副本,而不是对象本身。

实际上,您正在尝试这样做:

int blah() { int blah = 5; return blah; }
blah() = 99;

如您所见,这显然是错误的。

它确实取决于您执行分配的顺序,因为只有当您通过使左侧的分配发生在右侧的分配之前更改分配的自然顺序时才会出现此问题,例如 Oli 在评论中的示例关于这个答案:

(a = b) = c

另一个原因是消除不必要的复制,尽管编译器优化可能会带走这种好处。

您可以在此处阅读有关左值和右值的更多信息:http://msdn.microsoft.com/en-us/library/bkbs2cds.aspx

【讨论】:

  • 但这只有在你做一些像(a = b) = c这样不起眼的事情时才重要。
  • @Oli 我真的不明白你的评论,或者为什么它只在你改变作业顺序时才重要。
  • @Seth:因为a = b = c 被评估为a = (b = c)。显然,在这种情况下,operator= 是按引用返回还是按值返回并不重要。
  • @Oli 哦,是的,我明白你对订单的意思了。而代码 sn-p 只是为了演示当您执行您所做的 ((a = b) = c) 并且您按值返回时,他本质上在做什么。
【解决方案2】:

是的,但原因可能与优先级无关,也可能无关。返回引用而不是值的原因与将 rhs (在您的示例中)作为常量引用而不是值传递的原因相同:更好的性能。所以你可以只返回你想要的值,但要考虑到可能会创建一个副本。

您还必须考虑您的课程是否准备好复印。

【讨论】:

    【解决方案3】:

    您当然可以使用非引用返回类型声明operator =。事实上,在我实现它的极少数情况下,我通常让它返回 void,因为我不认为多次赋值或测试赋值结果是 C++ 的最大特性之一。

    【讨论】:

    • +1 表示事实正确性。虽然我对返回void 的想法提出异议!您班级的大多数用户(假设这些用户不仅仅是您!)都希望能够做到a = b = c,尽管这可能很糟糕。
    • 我同意你的观点。但是大多数人不阅读这类事情的文档(原则上最不意外)。您同样可以很好地记录您的 operator+ 执行乘法这一事实!
    • @Oli 正如我所说,我很少实现 operator=。最后一次是因为一些引用计数的事情(几年前),我发现我对多重赋值下的引用计数发生了什么感到困惑(所以上帝知道用户会怎么做),所以我阻止了它.而且我确实认为这是该语言的错误功能 - 我从不编写像 x = y = z 这样的代码,如果我在代码审查中遇到这种情况,我会不高兴。
    【解决方案4】:

    你可以按值返回,没有什么可以阻止你。人们所说的“链接”是(a = b) = c之类的语句,其作用是将b赋值给a,然后将c赋值给a。这几乎没有实际用途,因此如果您选择按值返回,那很好。

    目前的情况来自这样一个事实,即对于原语,赋值是这样定义的。因此,编译器提供的赋值运算符的工作方式相同,并且通常您希望重载的运算符尽可能地表现得像它们的内置对应物。但是,在这种特殊情况下,鉴于该特定构造的相对模糊性,您不太可能通过改变该行为来混淆任何人。只要你不做一些完全出乎意料的事情,比如返回一个布尔值来指示分配是否成功,就没有关系。

    【讨论】:

      【解决方案5】:

      我发现最好让编译器自动生成operator=()。在您确实需要指定它的情况下(很可能是深拷贝),我不会对它做任何非标准的事情。这只会让其他开发者感到困惑。

      别太聪明:)

      【讨论】:

      • 你必须有点聪明:如果你的类成员有一个指针,它将在构造函数中动态分配,你如何想象生成的 operator= 的行为?在这种情况下,如果你写 a = b; a 的相同指针成员将指向相同的内存...
      猜你喜欢
      • 1970-01-01
      • 2018-11-05
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      相关资源
      最近更新 更多