rhs是如何工作的?

5

我理解rhs代表右手边,但我不明白编译器如何理解“rhs”指的是右手边。有人能解释一下在什么情况下会需要这种重载吗?

MyArray<T>& operator=(const MyArray<T>& rhs); 

3
rhs只是参数名称。 - George Sovetov
6个回答

17
编译器并不知道 rhs 代表 "right hand side",实际上该变量的名称可以是任何你喜欢的名字。
编译器 "知道" 如何格式化这个语句是因为 operator= 的语法要求它必须是这种方式。
class A
{
public:
   A& operator=(const A& other);
};

该语言定义了使用此运算符的形式为:

A a, b;
a = b;

以上代码调用了A::operator=(const &other),将名称为aA实例作为赋值操作符的左操作数,使用名称为bA实例作为右操作数other


4
标准的同类型实例赋值运算符的原型如下: MyArray<T>& operator=(const MyArray<T>& rhs); 函数参数通常被命名为rhs,因为当调用运算符时它出现在赋值的右侧。这样做可以提高源代码的可读性。

3

rhs只是人们通常用来表示该运算符的名称,它没有特殊含义。该运算符的定义方式总是使参数成为右侧元素。


rhs 的意思是什么?我知道它可能代表“右手边”,但实际上这是什么意思? - Caio V.
“Right Hand Side” 是正确的。这就是它的意思。 - The Bic Pen

2
如果你做了这样的事情:
int a = 5;
int b = 3;
a = b;

任务部分实际上只是一个函数调用:

a.operator=(b);

没有什么特别的事情发生。参数名称并不重要,只有由返回类型和参数类型组成的签名才是重要的,而不是名称。


2

与任何函数一样,你可以将参数命名为任何你想要的名称。

以赋值运算符为例,如果你有这样一个示例:

MyArray<int> arr1, arr2;
arr1 = arr2;

这相当于

MyArray<int> arr1, arr2;
arr1.operator=(arr2);

“右侧”仅作为参数传递给普通成员函数。

1
我假设MyArray会有以下这样的结构。
    class MyArray{
public:
       int* arr;
       int len;
       MyArray( int l ){
          arr = new int[l];
          len = l;
       }
       ~MyArray(){
          delete [] arr;
       }
    };

现在考虑这样一种情况,即存在两个MyArray对象。
MyArray ob1(3); 
for( int i=0; i<3; i++ )
   ob1[i]=i*i; // ob1 = {0, 1, 4}
MyArray ob2(3);
for( int i=0; i<3; i++ )
   ob2[i]=i+1; // ob2 = {1, 2, 3}

现在,如果我们执行ob1 = ob2;编译器会使arr1指向arr2,因此,如果Ob2被更改为{4,5,6},Ob1也会更改为{4,5,6},这称为浅拷贝。为了避免这种情况,我们添加了以下内容。
MyArray& operator=(const MyArray& rhs){
     for( int i=0; i<rhs.len; i++ ) this.arr[i] = rhs[i];
 }

现在,如果更改ob2,ob1将不会受到影响,因为我们复制了数组本身而不是指针副本。因此,这被称为深拷贝。这是=重载的主要场景之一。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接