6

在 C++ 中重载类的赋值运算符时,它的参数必须是引用吗?

例如,

class MyClass {
public:
...
MyClass & operator=(const MyClass &rhs);
...
}

是真的吗

class MyClass {
public:
...
MyClass & operator=(const MyClass rhs);
...
}

?

谢谢!

4

5 回答 5

9

重载赋值运算符的参数可以是任何类型,并且可以通过引用或值传递(好吧,如果类型不是可复制构造的,那么显然不能通过值传递)。

因此,例如,您可以有一个将 anint作为参数的赋值运算符:

MyClass& operator=(int);

复制赋值运算符是赋值运算符的一种特殊情况。它是任何与类具有相同类型的赋值运算符,无论是通过值还是通过引用(引用可以是 const 或 volatile 限定的)。

如果您没有显式实现某种形式的复制赋值运算符,那么编译器会隐式声明和实现一个。

于 2010-05-30T22:38:01.090 回答
5

通常,由您决定,没有必须。第一个变体是常见的和“规范的”,适用于任何赋值运算符实现。

当问题是速度时,我认为您应该阅读这篇关于按值传递技术的文章。这意味着在某些情况下,按值传递比通过 const 引用传递更有效。

还要提一下,您的第二个变体不需要const关键字,因为按值传递就像创建了一个副本,所以原始对象肯定不会改变。

于 2010-05-30T22:41:16.013 回答
5

C++ 运算符重载指南建议,赋值运算符获取 const 引用。根据该站点的说法,原因是我们不想更改参数(因为 const),而只想更改运算符的左侧。因此,通过引用传递它可以节省时间。

它还指出了为什么赋值运算符返回引用的原因 - 运算符链接。为了开始a = (b = 1)工作,有必要(b = 1)返回一个可以分配(=)的引用a

于 2010-05-30T22:45:14.940 回答
4

你知道异常安全分配的复制和交换习语吗?

MyClass& operator=(const MyClass& rhs)
{
    MyClass copy(rhs);
    swap(copy);
    return *this;
}

可以通过按值调用来简化(并且在某些情况下加快)实现:

MyClass& operator=(MyClass copy)
{
    swap(copy);
    return *this;
}
于 2010-05-31T06:08:54.977 回答
-2

好的,我遇到了这个问题,我找不到一个好的答案,所以我将分享我学到的东西。

您可以按值传递,这没有任何问题。(正如您在问题中所展示的那样。)

但是我们通过 const 引用传递参数的原因是函数不会对被调用的值进行实际复制。它被引用,所以它只是指向该值在内存中的任何位置。

这节省了处理时间,特别是如果它有成千上万个名字的大东西......在这种情况下,节省的时间几乎没有。

对于 const,这可以确保函数的用户不会更改引用的值,因为它可能会被更改,因为您可以访问内存中的原始位置,因为它是通过引用传递的。如果您的函数定义实际上更改由 const reference 调用的参数的值,这将是编译器错误,它不会让你这样做。因为当你输入 const 时,你是在告诉编译器这个值不能改变。

于 2014-02-28T22:38:49.360 回答