源代码如下:
#include <iostream>
#include <string>
using namespace std;
string version1( string & s1, const string & s2); //此函数的入参为两个字符串引用,返回值为string
const string & version2( string & s1, const string & s2);//此函数的入参为两个字符串引用,返回值为指向字符串的引用
const string & version3( string & s1, const string & s2);//此函数的入参为两个字符串引用,返回值为指向字符串的引用
int main ()
{
string Isaid="It's not my faluts!";
string copy;
string result;
copy=Isaid;
cout << " I said: "<< Isaid<< endl;
result=version1(Isaid,"@@@@");
cout << " Now I said:(version1) "<< result<< endl;
cout << "just now I said: "<< Isaid<< endl;
result=version2(Isaid,"####");
cout << " Now I said:(version1) "<< result<< endl;
cout << "just now I said: "<< Isaid<< endl;
Isaid=copy;
result=version3(Isaid,"****");
cout << " Now I said:(version1) "<< result<< endl;
cout << "just now I said: "<< Isaid<< endl;
_sleep(8000);
}
string version1( string & s1, const string & s2)
{
string tmp;
tmp=s2+s1+s2;
return tmp;
}
const string & version2( string & s1, const string & s2)
{
s1=s2+s1+s2 ;
return s1;
}
const string & version3( string & s1, const string & s2)
{
string tmp;
tmp=s2+s1+s2;
return tmp;
}
此代码运行到version3时崩溃;
首先分析version1():
此函数在函数内新建了一个string对象,但是在函数调用完毕后,该对象的内存即释放,所以如果返回指向该string对象(tmp)的引用的话是不可行的。
而返回string对象的话,tmp的内容会被复制到一个临时的返回存储单元中,并在main函数中将返回存储单元中的内容复制给result(见红色代码);
然后分析version2();
此函数返回的是指向string的引用,但因为该函数修改的是传入的参数s1,并未创建临时对象。另外,修改的是s1而不是s2,因为s2是const的,不能修改。所以返回是安全的。
最后分析version3();
此函数在函数体内新建了一个string对象(tmp),并试图返回对其的引用。因为在函数调用完毕后,tmp变量是要释放的,对于main函数来说,这个变量及内存是不存在的,所以指向其的引用就是非法的。指向一个不存在的内存。所以程序报错。