1. 程式人生 > >14. 函式返回值為引用?

14. 函式返回值為引用?

函式返回值可以是引用嗎?

當然可以,只是在函式返回引用的時候需要注意幾點。以下給出討論!

函式在返回值的時候,會產生一個臨時變數作為函式返回值的副本;而函式在返回引用的時候,不會產生副本!那麼既然是引用,那麼到底是引用誰呢?

首先,我們知道要清楚函式返回引用的幾種常見形式:

1)引用函式的引數,當然該引數(s1、s2)也是一個引用。

   const string &shorter_String(const string &s1,const string &s2)
      {
             return s1.size()<s2.size()?s1:s2;
      }

 以上函式的返回值是引用型別無論返回s1或是s2,呼叫函式和返回結果時,都沒有複製這些string物件。簡單的說,返回的引用是函式的引數s1或s2,同樣s1和s2也是引用,而不是在函式體內產生的

2)不要返回區域性物件的引用,函式體內區域性物件是不能被引用的,因為函式呼叫完區域性物件會被釋放。

 const string &mainip(const string &s)
      {
             string ret=s;
             return ret;
      }

當函式執行完畢,程式將釋放分配給區域性物件的儲存空間。此時,對區域性物件的引用就會指向不確定的記憶體。

3)在類的成員函式中,返回類物件的引用(不能是函式內定義的類物件(會釋放掉)),一般為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;  
}  

引用作為返回值,必須遵守以下規則:

(1)不能返回區域性變數的引用。主要原因是區域性變數會在函式返回後被銷燬,因此被返回的引用就成為了"無所指"的引用,程式會進入未知狀態。

(2)不能返回函式內部new分配的記憶體的引用。雖然不存在區域性變數的被動銷燬問題,可對於這種情況(返回函式內部new分配記憶體的引用),又面臨其它尷尬局面。例如,被函式返回的引用只是作為一 個臨時變量出現,而沒有被賦予一個實際的變數,那麼這個引用所指向的空間(由new分配)就無法釋放,造成memory leak(記憶體洩露)。

(3)可以返回類成員的引用,但最好是const。主要原因是當物件的屬性是與某種業務規則(business rule)相關聯的時候,其賦值常常與某些其它屬性或者物件的狀態有關,因此有必要將賦值操作封裝在一個業務規則當中。如果其它物件可以獲得該屬性的非常 量引用(或指標),那麼對該屬性的單純賦值就會破壞業務規則的完整性。