第一个程序:
#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; }
|