我从“Effective c ++”中读到了这个,这是Col.10。 它说这是让赋值运算符返回对* this的引用的好方法。 我写了一个代码片段来测试这个想法。我在这里重写了赋值运算符。并对其进行了测试。一切都好。 但是当我删除那个操作符覆盖时,一切都是一样的。这意味着,链接任务仍然有效。那么,我错过了什么?这是为什么?你们需要一些解释,感谢你们。
#include <iostream>
using namespace std;
class Widget{
public:
Widget& operator=(int rhs)
{
return *this;
}
int value;
};
int main()
{
Widget mywidget;
mywidget.value = 1;
Widget mywidget2;
mywidget2.value = 2;
Widget mywidget3 ;
mywidget3.value = 3;
mywidget = mywidget2 = mywidget3;
cout << mywidget.value<<endl;
cout << mywidget2.value<<endl;
cout << mywidget3.value<<endl;
}
答案 0 :(得分:6)
如果完全删除operator=
方法,编译器将创建一个默认的operator=
,它实现浅拷贝 1 并返回对{{1}的引用}。
顺便提一下,当你写
时*this
您实际上是在调用此默认值mywidget = mywidget2 = mywidget3;
,因为您的重载运算符旨在与右侧的operator=
一起使用。
链式赋值将停止工作,相反,如果您返回一个值,int
引用(=&gt;您将获得编译错误)或对{{1}不同的引用(反直觉的东西将开始发生)。
部分相关:copy and swap idiom,即编写赋值运算符的完美方式。强烈建议您阅读是否需要撰写const
*this
将执行,就好像左手操作数的每个成员与右手操作数的每个成员之间有一个赋值。这意味着对于原始类型,它将是一个“残酷的”按位复制,在90%的情况下,对于拥有资源的指针是不可行的。答案 1 :(得分:4)
问题涉及两个不同的概念,是否应该定义operator=
以及是否应该返回对象的引用。
您应该考虑三者的规则:如果您定义复制构造函数,赋值运算符或析构函数之一,您应该定义三个他们围绕该规则的基本原理是,如果您需要提供析构函数,则意味着您正在管理资源,并且在这样做时,可能是默认的复制构造函数和赋值运算符不会削减它。例如,如果通过原始指针保存内存,则需要在析构函数中释放内存。如果未提供复制构造函数和赋值运算符,则将复制指针,并且两个不同的对象将尝试释放指针所占用的内存。
虽然指针是最常见的示例,但这适用于任何资源。例外情况是你禁用复制构造和赋值的类 - 但是你再次定义它们禁用。
在问题的第二部分,或者你是否应该返回对象的引用,你应该。与所有其他运算符重载一样,原因在于模仿基本类型的现有运算符通常是一个很好的建议。这有时由引号给出:在重载运算符时,按int
执行。
答案 2 :(得分:1)
Widget& operator=(int rhs)
这允许您将 int 分配给Widget - 例如mywidget = 3;
制作Widget& operator=(Widget const & rhs)
- 您的mywidget = mywidget2 = mywidget3;
行会被调用。
你不需要一个operator=(Widget const & rhs)
- 默认应该没问题。
此外,最好添加例如cout << "operator=(int rhs)\n";
到您的自定义运算符 - 然后您会发现代码中根本没有调用它。