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