第一个程序:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct sysop
  {
char name[26];
char quote[64];
int used;
};
const sysop & use(sysop & sysopref);//function with a reference return type
int main(int argc, char* argv[])
  {
// NOTE: some implementations require using the keyword static
// int the two structure declarations to enable initialization
sysop looper=
 {
"Rick \"Fortran\" Looper",
"I'm a goto kind of guy.", //记住无遗漏逗号
0
};
use(looper); //looper is type sysop
cout<<"Looper: "<<looper.used<<" use(s)\n";
sysop copycat;
copycat = use(looper);
cout<<"Looper: "<<looper.used<<" use(s)\n";
cout<<"Copycat: "<<copycat.used<<" use(s)\n";
cout<<"use(looper): "<<use(looper).used<<" use(s)\n";
return 0;
}

const sysop & use(sysop & sysopref)
  {
cout<<sysopref.name<<" says:\n";
cout<<sysopref.quote<<endl;
sysopref.used++;
return sysopref;
// 通常,返回机制将返回值复制到临时存储区域中,随后调用程序将访问该区域。
// 然而,返回引用意味着调用程序将直接访问返回值,而不需要拷贝。通常,引
// 用将指向传递给函数的引用,因此调用函数实际上是直接访问自己的一个变量。
}
第二个程序:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
string version1(const string & s1,const string & s2);
const string & version2(string & s1, const string & s2); //has side effect
const string & version3(string & s1, const string & s2); //bad design
int main(int argc, char* argv[])
  {
string input;
string copy;
string result;

cout<<"Enter a string: ";
getline(cin, input);
copy = input;
cout<<"Your string as entered: "<<input<<endl;
result = version1(input, "***");
cout<<"Your string enhanced: "<<result<<endl;
cout<<"Your original string: "<<input<<endl;

result=version2(input,"###");
cout<<"Your string enhanced: "<<result<<endl;
cout<<"Your original string: "<<input<<endl;
cout<<"Resetting original string.\n";
input = copy;
result = version3(input, "@@@");
cout<<"Your string enhanced: "<<result<<endl;
cout<<"Your original string: "<<input<<endl;
return 0;
}

 /**//* 接受两个string参数,并使用string类的相加功能来创建满足要求的新字符串。
* 这两个参数都是const引用。如果使用string对象作为参数,最终结果将不变。
* 在这种情况下,s1和s2将为string对象。使用引用的效率更高,因为函数不需
* 要创建新的string对象,并将原来对象中的数据复制到新对象中。
*
* temp是一个新的string对象,只在函数version1()中有效,该函数执行完毕后,
* 它将不再存在。因此,将返回指向temp的引用不可行,因此该函数的返回类型
* 是string,这意味着temp的内容将被复制到一个临时返回存储单元中。然后在
* main()中,该返回存储单元的内容将被复制到一个名为result的string中。
*/
string version1(const string & s1, const string & s2)
  {
 /**//* 读者可能注意到一点,"***"是const char *,而形参s2是const string &
* 这是因为,第一,string类定义了一种char *到string得转换功能,这使得
* 可以使用C-style string来初始化string对象,第二,前面讨论的类型为const
* 引用的形参的一个属性。假设实参的类型与引用参数类型不匹配,但可被转换
* 为引用类型,程序将创建一个正确类型的临时变量,使用转换后的实参值来初
* 始化它,然后传递一个指向该临时变量的引用。这种属性的结果是,如果形参
* 类型为const string &,在调用函数时,使用的实参可以是string对象或C-style
* string,如用引号括起的字符串字面量、以空字符结尾的char数组或指向char的
* 指针变量
*/
string temp;
temp=s2+s1+s2;
return temp;
}


 /**//* version2()不能创建临时string对象,而是直接修改原来的string对象
* 该函数可以修改s1,因为不同于s2,s1没有被声明为const。
*/
const string & version2(string & s1, const string & s2)
  {
s1=s2+s1+s2;
// safe to return reference passed to function
return s1;
}

 /**//* 存在一个致命的缺陷:返回一个指向version3()中声明的变量的引用。这个函数
* 能够通过编译(但编译器会发出警告),但当程序视图执行该函数时将崩溃。是
* 因为程序视图引用已经释放的内存。
*/
const string & version3(string & s1, const string &s2)//bad design
  {
string temp;
temp=s2+s1+s2;
// unsafe to return reference to local variable
return temp;
}
|