在一些资料和书籍中,都告诉我们如果要实现自定义类的连续赋值重载,那么就需要将赋值重载的返回值定义为引用。
但直接返回实例依然可以实现连续赋值的功能。
class MYString
{
private:
char* m_pdata;
public:
MYString(char *pData=nullptr);
MYString(const MYString&str);
MYString operator+(const MYString& a);
MYString operator=(const MYString& a);
char* getdata();
~MYString();
};
MYString MYString::operator=(const MYString& a)
{
if(this==&a)
{
return *this;
}
delete []m_pdata;
this->m_pdata = nullptr;
this->m_pdata = new char[strlen(a.m_pdata) + 1];
strcpy(this->m_pdata,a.m_pdata);
return *this;
}
我将赋值重载的返回直接设置为了MYString实例,然后在main函数中进行验证:
int main(int argc, char* argv[])
{
MYString a("abc");
MYString b("def");
MYString c("ghi");
MYString d("");
printf("a.mdata=%s,b.m_data=%s,c.m_data=%s\n",a.getdata(),b.getdata(),c.getdata());
// d=a+b+c;
d=b=c=a;
printf("the data is %s\n",d.getdata());
return 0;
}
程序的输出如下:
这意味着程序并没有出现像一些资料中提示的不使用引用就无法通过编译的情况,能够正常的使用。那么是否使用引用作为赋值重载的返回值真正的区别时什么呢?
在构造函数和析构函数中打印一些输出,以检验两者的区别,同样的主函数调用方法:
int main(int argc, char* argv[])
{
MYString a("abc");
MYString b("def");
MYString c("ghi");
MYString d("");
printf("a.mdata=%s,b.m_data=%s,c.m_data=%s\n",a.getdata(),b.getdata(),c.getdata());
// d=a+b+c;
d=b=c=a;
printf("the data is %s\n",d.getdata());
return 0;
}
当使用对象作为返回时,程序的输出为:
当使用引用作为返回值时,程序的输出为:
也就是说,如果使用引用作为返回值,则每次赋值操作都不必在调用一次拷贝构造函数和析构函数,可以避免一些无端的开销,这才是需要使用引用作为返回值的真正原因。