C++函式返回引用
注:C++ 有三種傳遞方式:值傳遞,指標傳遞,引用傳遞
返回 “值” 和返回 “引用” 是不同的
函式返回值時會產生一個臨時變數作為函式返回值的副本,而返回引用時不會產生值的副本,既然是引用,那引用誰呢?這個問題必須清楚,否則將無法理解返回引用到底是個什麼概念。以下是幾種引用情況:
一、千萬不要返回區域性物件的引用
const string &mainip(const string &s)
{
string ret=s;
return ret;
}
當函式執行完畢,程式將釋放分配給區域性物件的儲存空間。此時,對區域性物件的引用就會指向不確定的記憶體。 同理,指標也是這樣,返回指標的時候,不能指向區域性臨時變數,否則指標將變為野指標;
二、引用函式的引數,當然該引數也是一個引用
const string &shorterString(const string &s1,const string &s2)
{
return s1.size()<s2.size()?s1:s2;
}
以上函式的返回值是引用型別。無論返回s1或是s2,呼叫函式和返回結果時,都沒有拷貝這些string物件。簡單的說,返回的引用是函式的引數s1或s2,並且引數s1、s2也是引用,不是在函式體內產生的。函式體內區域性物件是不能被引用的,因為函式呼叫完區域性物件會被釋放。
三、返回 this 指向的物件
在類的成員函式中,返回引用的類物件,當然不能是函式內定義的類物件(會釋放掉),一般為 this 指向的物件,典型的例子是 string類的賦值函式。
String& String::operator =(const String &str) //注意與“+”比較,函式為什麼要用引用呢?a=b=c,可以做為左值 { if (this == &str) { return *this; } delete [] m_string; int len = strlen(str.m_string); m_string = new char[len+1]; strcpy(m_string,str.m_string); return *this; }
四、引用返回this 的成員變數,或者 引用引數的成員變數
原標題為:引用返回左值(上例的=賦值也是如此,即a=b=c是可以的)
原文這裡表達不清晰,因為只要是引用,都可以作為左值使用。只因為下面的例子一般用在等號左邊,當左值使用。 可以定義一個和返回值一樣的引用型別,來接受函式的返回值,操作此引用值,和直接操作函式的引數是一樣的,引用都是使用引用傳遞;
char &get_val(string &str,string::size_type ix)
{
return str[ix];
}
// 使用語句呼叫:
string s("123456");
cout<<s<<endl;
get_val(s,0)='a';
cout<<s<<endl;
這種情況,和第二種是一樣的,只不過是返回了引數(引用型別)的一部分。也可以不作為左值,故修改如下:
char &ch = get_val(s,0);
ch = ‘A’;
此句進行的都是引用傳遞,故執行之後,s[0] 就變為了 A,s為“A23456”; 此外,可以返回引用引數的成員變數,親測有效。似乎不是區域性臨時變數,只要函式結束之後記憶體沒有被銷燬的,作為引用返回都沒問題:
QString& Test(Student &stu)
{
return stu.m_name;
}
QString & Student::getRName()
{
return (*this).m_name;
}
五、最後轉上一段code作為總結
#include<iostream>
using namespace std;
string make_plural(size_t,const string&,const string&);
const string &shorterString(const string &,const string &);
const string &mainip(const string&);
char &get_val(string &,string::size_type);
int main(void) {
cout<<make_plural(1,"dog","s")<<endl;
cout<<make_plural(2,"dog","s")<<endl;
string string1="1234";
string string2="abc";
cout<<shorterString(string1,string2)<<endl;
cout<<mainip("jiajia")<<endl;
string s("123456");
cout<<s<<endl;
get_val(s,0)='a';
cout<<s<<endl;
getchar();
return 0;
}
//返回非引用
string make_plural(size_t i,const string &word,const string &ending)
{
return (i==1)?word:word+ending;
}
//返回引用
const string &shorterString(const string &s1,const string &s2)
{
return s1.size()<s2.size()?s1:s2;
}
//禁止返回區域性物件的引用(我的dev c++ 沒有報錯,比較可怕)
const string &mainip(const string &s)
{
string ret=s;
return ret;
}
//引用返回左值
char &get_val(string &str,string::size_type ix)
{
return str[ix];
}
---------------------
本文來自 非長道 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/qq_33266987/article/details/53516977?utm_source=copy