有没有人发现需要将复制赋值运算符的返回参数声明为 const?
复制赋值运算符具有通常的签名:
my_class & operator = (my_class const & rhs);
以下签名有任何实际用途吗?
my_class const & operator = (my_class const & rhs);
您只能定义其中之一,但不能同时定义两者。
The copy assignment operator has the usual signature:
my_class & operator = (my_class const & rhs);
Does the following signature have any practical use?
my_class const & operator = (my_class const & rhs);
You can only define one or the other, but not both.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(7)
一个答案反映了在C++中重载赋值运算符:
返回一个const&
仍然允许赋值链:
a = b = c;
但将不允许一些更不寻常的用途:
(a = b) = c;
请注意,这使得赋值运算符的语义类似于 C 中的语义,其中 返回的值>=
运算符不是左值。在 C++ 中,标准对其进行了更改,因此 =
运算符返回左操作数的类型,因此结果是左值。但是正如史蒂夫·杰索普在另一个答案的评论中指出的,虽然使得编译器
(a = b) = c;
甚至可以接受内置函数,结果是内置函数的未定义行为,因为 a
被修改了两次而没有中间序列点。对于带有 operator=()
的非内置函数,可以避免这个问题,因为 operator=()
函数调用充当序列点。
我认为返回 const& 没有问题,除非您想专门允许左值语义(并设计类以确保它与这些语义一起合理地运行)。如果您的用户想要对 operator=()
的结果做一些不寻常的事情,我希望该类禁止它,而不是希望它偶然而不是设计正确。
还。请注意,当你说:
您只能定义其中之一,但不能同时定义两者。
这是因为 C++ 中的函数签名没有考虑返回值类型。然而,您可以有多个 operator=()
赋值运算符,它们采用不同的参数并返回适合参数类型的不同类型:
my_class& operator=( my_class& rhs);
my_class const& operator=(my_class const& rhs);
但我不完全确定这会给您带来什么。在这两种情况下,分配给的对象(可能是返回的引用)都是非常量的,因此没有逻辑理由仅仅因为 < 的右侧就返回 const&
code>= 是 const
。但也许我错过了一些东西......
《Effective C++》解释说,这会破坏与 C++ 内置类型的兼容性。
你可以用普通的 int 来做到这一点:
(x = y) = z;
所以他认为,无论这看起来多么愚蠢,人们也应该能够对自己的类型做同样的事情。
这个例子在第二版中有,但在第三版中不再有。然而,第三版第 10 条中的这句话仍然说明了同样的情况:
[...] 赋值返回对其左侧参数的引用,这是在为类实现赋值运算符时应遵循的约定:
class Widget {
public:
...
Widget& operator=(const Widget& rhs) // return type is a reference to
{ // the current class
...
return *this; // return the left-hand object
}
...
};
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
将复制赋值的返回类型设置为非常量引用的主要原因是它是标准中“可赋值”的要求。
如果您将返回类型设置为 const 引用,那么您的类将无法满足在任何标准库容器中使用的要求。
The principle reason to make the return type of copy-assignment a non-const reference is that it is a requirement for "Assignable" in the standard.
If you make the return type a
const
reference then your class won't meet the requirements for use in any of the standard library containers.