在这里我理解rhs意味着右手边但我不明白编译器如何理解“rhs”指的是右手边。并且有人可以解释在哪种情况下这种重载是必要的吗?
MyArray<T>& operator=(const MyArray<T>& rhs);
答案 0 :(得分:10)
编译器不知道rhs
代表“右手边”,实际上该变量的名称可以是你喜欢的任何东西。
编译器“知道”如何格式化它,因为operator=
的语法要求它是这样的。
class A
{
public:
A& operator=(const A& other);
};
该语言定义此运算符的用法采用以下形式:
A a, b;
a = b;
上面的代码针对名为A::operator=(const &other)
的{{1}}实例调用A
,并使用名为a
的{{1}}实例作为A
答案 1 :(得分:3)
相同类型实例的标准赋值运算符具有原型
MyArray<T>& operator=(const MyArray<T>&);
名称rhs
通常赋予函数参数,因为它在调用运算符时出现在赋值的右侧。它提高了源代码的易读性,就是这样。
答案 2 :(得分:2)
rhs
只是人们通常用于该运营商的名称,它没有特殊含义。定义运算符的方式总是使参数成为右手元素。
答案 3 :(得分:2)
如果您执行以下操作:
int a = 5;
int b = 3;
a = b;
赋值部分实际上只是一个函数调用:
a.operator=(b);
没什么特别的。参数名称并不重要,只是由返回类型和参数类型组成的签名,而不是名称。
答案 4 :(得分:2)
与任何函数一样,您可以调用任何您想要的参数。
将您的示例与赋值运算符一起使用,如果您有类似
的内容MyArray<int> arr1, arr2;
arr1 = arr2;
这相当于
MyArray<int> arr1, arr2;
arr1.operator=(arr2);
“右侧”只是作为参数传递给普通成员函数。
答案 5 :(得分:1)
我假设MyArray会有这样的结构。
class MyArray{
public:
int* arr;
int len;
MyArray( int l ){
arr = new int[l];
len = l;
}
~MyArray(){
delete [] arr;
}
};
现在考虑一个MyArray有2个对象的场景
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将不会受到影响,因为我们已经自己复制了数组而不是指针copy.So这称为深拷贝。这是=重载的主要方案之一。