为什么我不能用非引用返回类型定义operator=?
C++ 中类中的 Operator= 是这样声明的:
MyType & operator=(const MyType & rhs);
它的推理就像它是链接所必需的。但是,由于 operator= 具有正确的优先级,因此返回值应该足够了。
Operator= in C++ inside a class is being declared like this:
MyType & operator=(const MyType & rhs);
It is reasoned like it is necessary for chaining. But, as operator= has right precedence, then returning the value should be enough.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您当然可以声明具有非引用返回类型的
operator =
。事实上,在我实现它的极少数情况下,我通常会使其返回void
,因为我不认为多重赋值或测试赋值结果是 C++ 最伟大的功能之一。You certainly can declare
operator =
with a non-reference return type. In fact, on the very rare occasions I implement it, I normally make it returnvoid
as I don't think that multiple assignments, or testing the result of assignment, are one of C++'s greatest features.是的,但原因可能与优先级无关,也可能无关。返回引用而不是值的原因与将 rhs(在您的示例中)作为常量引用而不是值传递的原因相同:更好的性能。因此,您可以根据需要仅返回值,但要考虑到可能会创建副本。
此外,您还必须考虑您的班级是否准备好复印。
Yes, but the reason may or may not have nothing to do with precedence. The reason to return a reference, and not a value, is the same one for passing rhs (in your example) as a constant reference instead of a value: better performance. So you can return only the value if you want, but take into account that a copy may be created.
Also you have to take into account whether your class is prepared or not for copies.
如果不按引用返回,则按值返回,并且无法分配给值,因为只有左值是可分配的。即使可以,也没关系,因为分配给它的对象很快就会被销毁,因为它只是对象的副本,而不是对象本身。
实际上,您正在尝试这样做:
正如您所看到的,这显然是错误的。
但这确实取决于你做作业的顺序,因为只有当你改变作业的自然顺序,让左边的一个发生在右边的一个之前,这个问题才会出现,就像奥利在这个答案的评论中的例子一样:
另一个原因是消除不必要的复制,尽管编译器优化可能会消除这种好处。
您可以在此处阅读有关左值和右值的更多信息:http://msdn.microsoft.com /en-us/library/bkbs2cds.aspx
If you don't return by reference, you are returning by value, and you can't assign to a value, because only lvalues are assignable. Even if you could, it wouldn't matter because the object you assigned to would be destroyed soon after you assigned to it because it's only a copy of the object, not the object itself.
In effect, you are trying to do this:
Which as you can see is obviously wrong.
It does depend on the order in which you do assignments though, because this issue will only come up when you change the natural order of assignments by making one on the left happen before one on the right, like Oli's example in a comment on this answer:
Another reason is to eliminate unnecessary copying, though compiler optimisations might take away that benefit.
You can read more on lvalues and rvalues here: http://msdn.microsoft.com/en-us/library/bkbs2cds.aspx
你可以按值返回,没有什么可以阻止你。人们所说的“链接”是像
(a = b) = c
这样的语句,它具有将b
分配给a
的效果,并且然后将c
分配给a
。这几乎没有实际用途,所以如果您选择按值返回,那就完全没问题了。当前的情况来自这样一个事实:对于原语来说,赋值就是这样定义的。因此,编译器提供的赋值运算符以相同的方式工作,并且通常您希望重载运算符尽可能表现得像其内置对应运算符一样。不过,在这种特殊情况下,考虑到该特定构造的相对模糊性,您不太可能通过改变该行为来迷惑任何人。只要你不做一些完全出乎意料的事情,比如返回一个布尔值来指示分配是否成功,那就没关系。
You can return by value, there is nothing to stop you. The "chaining" people refer to is statements like
(a = b) = c
, which has the effect of assigningb
toa
, and then assigningc
toa
. This has almost no practical use, so if you chose to return by value that's perfectly fine.The current state of affairs comes from the fact that for primitives, assignment is defined that way. So the compiler provided assignment operator works the same way, and generally you want overloaded operators to behave like their built in counterparts whenever possible. In this particular case, though, given the relative obscurity of that particular construct, you are unlikely to confuse anybody by changing that behavior. So long as you don't do something completely unexpected, like returning a boolean to indicate whether or not the assignment succeeded, it shouldn't matter.
我发现最好让编译器自动生成operator=()。在您确实需要指定它的情况下(最有可能的是深层复制),我不会对其执行任何非标准操作。这只会让其他开发者感到困惑。
别太聪明了:)
I find it's best to let the compiler to automatically generate operator=(). In the cases where you do actually need to specify it (for a deep copy most likely), I wouldn't do anything non-standard to it. This will only confuse other developers.
Don't be too clever :)