rhs 是如何工作的?

How does rhs work?

在这里我理解 rhs 表示右手边,但我不明白编译器如何理解 "rhs" 指的是右手边。有人可以解释在什么情况下需要这种重载吗?

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

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

编译器不知道 rhs 代表 "right hand side",实际上该变量的名称可以是您喜欢的任何名称。

编译器 "knows" 如何格式化它,因为 operator= 的语法要求它是这样的。

class A
{
public:
   A& operator=(const A& other);
};

该语言定义了该运算符的用法,采用以下形式:

A a, b;
a = b;

上面的代码针对名为 aA 实例调用 A::operator=(const &other),并将名为 bA 实例用作 [=19] =].

如果你这样做:

int a = 5;
int b = 3;
a = b;

赋值部分实际上只是一个函数调用:

a.operator=(b);

没什么特别的。参数名称无关紧要,只是由 return 类型和参数类型组成的签名,而不是名称。

与任何函数一样,您可以随意调用参数。

将你的例子与赋值运算符一起使用,如果你有类似

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

相当于

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

"right hand side" 只是作为参数传递给普通成员函数。

相同类型实例的标准赋值运算符具有原型

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

通常将名称 rhs 赋予函数参数,因为它在调用运算符时出现在赋值的右侧。它提高了源代码的易读性,仅此而已。

我假设 MyArray 将具有这样的结构。

    class MyArray{
public:
       int* arr;
       int len;
       MyArray( int l ){
          arr = new int[l];
          len = l;
       }
       ~MyArray(){
          delete [] arr;
       }
    };

现在考虑一个场景,其中有 2 个 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},这称为 shallow copy.To 避免场景我们添加这个

MyArray& operator=(const MyArray& rhs){
     for( int i=0; i<rhs.len; i++ ) this.arr[i] = rhs[i];
 }

现在,如果更改 ob2,ob1 将不会受到影响,因为我们是自己复制数组而不是指针 copy.So,这称为深复制。这是 = 超载的主要场景之一。