1. 程式人生 > >C++函式返回引用

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