EFfective C++和More Effective C++中有讲解。
“条款23: 必须返回一个对象时不要试图返回一个引用”
“条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用”
为什么要返回引用呢——为了实现链式操作。
返回一个对象不行吗?为什么有时要返回引用呢?主要是为了实现链式操作。
看一个例子就明白了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
|
MyString& MyString::operator =(const MyString &other) { /*if (this != &other) { size = strlen(other.data); char *temp = new char[size + 1]; strcpy(temp, other.data); delete []data; data = temp; } return *this;*/ if (this != &other) { MyString strTmp(other); char *pTmp = strTmp.data; strTmp.data = data; data = pTmp; } return *this; }
|
当返回引用时,我们可以实现链式操作如 (s1 = s2) = s3.如果返回的是对象,就不能这么操作了!
MyString s1;
MyString s2;
MyString s3 = “hello”;
(s1 = s2) = s3;
如果返回的是引用,则s1被赋值为"hello";如果是局部对象,则s1没被赋值!
注意和+ – * /运算符重载相区别(返回局部对象):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
|
String String::operator +(const String &str) { String newstring; if (!str.m_string) { newstring = *this; } else if (!m_string) { newstring = str; } else { int len = strlen(m_string)+strlen(str.m_string); newstring.m_string = new char[len+1]; strcpy(newstring.m_string,m_string); strcat(newstring.m_string,str.m_string); } return newstring; }
|
何时返回引用呢
有两种情况可以返回引用。一种是普通函数,返回传入参数的引用;另一种是类方法函数,返回this对象的引用。
只要记住这两种情况,其他情况如果可以也是没什么意义的。
一、返回传入参数的引用。
如运算符<<的友元重载形式:
1 2 3 4 5
|
|
ostream& operator<< (ostream &out, MyString &s) { out << s.data; return out; }
|
二、返回this对象的引用。
即上面string的 = 运算符重载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
|
MyString& MyString::operator =(const MyString &other) { /*if (this != &other) { size = strlen(other.data); char *temp = new char[size + 1]; strcpy(temp, other.data); delete []data; data = temp; } return *this;*/ if (this != &other) { MyString strTmp(other); char *pTmp = strTmp.data; strTmp.data = data; data = pTmp; } return *this; }
|
最终总结:返回引用的情况有两种,一种是普通函数,返回传入参数的引用;另一种是类方法函数,返回this对象的引用。
不可以返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用(可能会造成内存泄露).