我是计算机科学专业的学生。在回答之前请完整阅读我的问题
今天在C ++课中我们学习了重载运算符,特别是赋值运算符,我的教授说了一些他不喜欢的东西:“只要相信我。”他在参考return *this
惯例时说出了这一行。
我问道,“但为什么?”他的答案很简单,“因为它是。”
我对这个答案不满意。
请考虑以下事项:
class length
{
private:
int inches, feet, yards;
public:
//getters, setters, etc.
Length operator=(const Length& Q)
{
this->inches = Q.inches;
this->feet = Q.feet;
this->yards = Q.yards;
return *this;
}
};
我理解基于无数问题和至少3本C ++书籍存在“公约”存在,因为它允许链式分配但为什么有必要以及如何它成了吗?
一个更深入的问题是this
如何为类的属性(IE this->inches
)提供单独的“子指针”(我的术语,而不是官方指针)?这是如何运作的? this->inches
只是偏移还是什么?
我的教授和我真的很感谢答案不仅仅是“因为它是如何完成的。”
请和谢谢
编辑:我认为我写这个问题很清楚;但是,根据我的反应,我认为存在误传。我试图了解公约的来源(我相信C的根源)以及为什么会这样。
答案 0 :(得分:3)
共识似乎是operator=
传统上返回* this以启用如下构造:
a = b = c
这是C扩展到类的传统行为。
顺便说一下,operator=
的签名应该是:
Length& operator=(const Length& Q);
因为您不想创建新的临时对象sa返回值
答案 1 :(得分:3)
由于您对“因为它是”的答案不满意,让我给您一个不同的答案:
重载运算符时,按int
执行
该建议的原因是遵循最少惊喜的原则,人们习惯于操作员以现有类型的特定方式查看和行为。当他们使用您的类型的运算符时,隐含的期望它将表现相同。
现在接下来的问题是为什么int
会这样做?为此,我没有明确的答案。它启用了一些奇特的语法,例如:(a = 3) = 5
,++(a = 3)
或(x = y).change()
,但不清楚这三种情况中的真实价值是什么。在第一种情况下,您可以直接分配5
,在另外两种情况下重写表达式,因为两个单独的表达式会使代码更具可读性。
我故意避免在前一个参数中使用a = b = c
的情况,因为这个案例支持运算符应该产生值或引用的想法,以便它可以用于稍后的分配但约定是返回可修改的引用,上面的表达式不需要这个。 const &
足以支持上述语法。 [然后再说一遍,语法真的需要吗?将其分成两个陈述的成本是多少?它不会更具可读性吗? (在许多情况下,它可能会更好,在某些情况下可能不会)]。
无论如何,要带回家的教训是遵循最少意外的原则,以及导致所有基本或其他标准类型的这种行为的理由,一旦它成为一个成语它最好跟随它。
答案 2 :(得分:2)
作业是一种表达方式。它既有效果(将一些数据从右侧复制到左侧)又有一个值。除非你想破坏惯例并使奇怪的事情发生,否则这个值就在左边(即this
)。这样if (a = b)
如果a
从作业中变为真,则a = b = c
为c
和a
分配b
。
最好通过引用返回this
,而不是this answer中所述的值,是因为它避免了不必要的复制。