问题描述
|
我从\“ 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;
}
解决方法
如果完全删除
operator=
方法,则编译器将创建默认值operator=
,该编译器将实现浅复制1并返回对*this
的引用。
顺便说一句,当你写
mywidget = mywidget2 = mywidget3;
您实际上是将此默认值称为operator=
,因为您的重载运算符旨在与右侧的int
一起使用。
链式分配将停止工作,相反,例如,如果您返回一个值,一个const
引用(=>您将得到编译错误)或对不同于*this
的引用(反常的东西将开始发生)。
部分相关:复制和交换习惯用法,即编写赋值运算符的理想方法。强烈建议您阅读,如果您需要写operator=
默认值operator=
的执行就像在左手操作数的每个成员和右手操作数的每个成员之间都有赋值一样。这意味着对于原始类型,它将是一个“原始”按位副本,在90%的情况下,对于拥有资源的指针来说,这是不可行的。
,这个问题涉及两个不同的概念,是否应该定义“ 1”以及是否应该返回对该对象的引用。
您应该考虑这三个规则:如果您定义复制构造函数,赋值运算符或析构函数之一,则应该定义三个。该规则的基本原理是,如果您需要提供一个析构函数,则意味着您正在管理资源,这样做的话,默认的复制构造函数和赋值运算符可能不会削减它。例如,如果通过原始指针保留内存,则需要释放析构函数中的内存。如果不提供复制构造函数和赋值运算符,则将复制指针,并且两个不同的对象将尝试释放该指针持有的内存。
虽然指针是最常见的示例,但这适用于任何资源。例外是在其中禁用副本构建和分配的类-但是,您再次以某种方式将其定义为禁用。
在问题的第二部分,或者是否应该返回对该对象的引用,都应该。与所有其他运算符重载一样,其原因是,通常最好还是模仿现有基本类型运算符的功能。有时用引号引起来:当重载运算符时,请像6那样做。
,Widget& operator=(int rhs)
这允许您将int分配给小部件-例如mywidget = 3;
做一个Widget& operator=(Widget const & rhs)
-您的mywidget = mywidget2 = mywidget3;
行会被调用。
虽然您不需要ѭ17-默认值应该可以。
另外,最好添加例如custom18ѭ给您的自定义运算符-那么您会发现它在代码中根本没有被调用。