最近看到C++的运算符重载,赋值运算符如=,+=,-=,.....,为什么operator=(),operator+=()...的返回值必须是对象的引用,书上说是保证这样的表达式赋值a=b=c,我把返回值改为按值返回,代码也能通过啊。
今天在看剑指offer时突然被这个问题困惑,为此上网查查,特此记录一下。
话不多说,先贴上代码
<span style="font-size:18px;">CMystring& operator=(const CMystring& str)
{
if(this == &str)
return *this;
delete []data;
data = NULL;
data = new char[strlen(str.data) + 1];
strcpy(data, str.data);
return *this;
}</span>
这是剑指offer上一个示例代码。我们就拿此分析一下。
其实对于重载赋值运算符,返回值是引用或者不是都行,代码都可以运行,之所以用引用是为了提高代码效率,为什么引用就会提高代码效率呢?
对于返回值是CMystring时(非引用)。返回时,会自动生成一个临时对象来保存返回的这个内容,然后通过拷贝构造函数返回给调用这个函数的对象(*this)。但是当返回值是CMystring&时,将直接返回(意思就是在函数中实际操作的就是调用这个函数的对象,不存在临时对象),就不存在这个临时对象了。节省了空间时间。为此效率较高。
结论:返回值是类型的引用,只是为了我们节省效率的一种方式,还有,临时对象具有常性(const)。
为了加深理解,看看下面例子---
按值返回有按值返回的好处
A fun(){
A a;
//...
return a; //一定要按值返回,不能返回局部对象的引用
}
按值返回的临时变量,也并不一定马上就会被析构
这样
A a;
a = fun();//fun返回一个临时对象,赋值给a后临时对象将会析构
而这样:
const A &b=fun();
fun返回值填入临时变量后,将临时变量的引用赋给变量b,由于有一个引用指向了这个临时变量,将不会再析构这个临时变量,相当于延长了这个临时变量的生命周期。
再来一个指针的
const A *c=&fun();
fun返回值填入临时变量后,将临时变量的指针赋给变量c,但这时候与引用不同,临时变量仍然会被析构,临时变量的生命期结束,b指向了一个已经被析构的对象,危险。
不过好像对于新的C++标准,需要一个const类型的引用才能指向临时对象,这样
const A &b=fun();
看到这里或许读者还有这个问题:
用引用时,为什么临时变量不会析构,用指针就会,这算不算指针跟引用的一个区别呢,
C++ primer上有提到这个问题,试验了一下也正确,算是规定吧,记住就行!!!