C++ 傳回值注意事項

來源:互聯網
上載者:User
一、預設情況下,函數的傳回值是按值傳遞的

這意味著得到控制權的函數將接收返回語句中指定的運算式的拷貝,例如:            

Matrix grow( Matrix* p ) {
    Matrix val;
 
     // ...
     return val;
}
grow()把儲存在 val 中的值的拷貝返回到調用函數,但調用函數不能用任何方式修改val 。

 

二、該預設行為可以被改變,一個函數可以被聲明為返回一個指標或一個引用

當函數返回一個引用時,調用函數接收 val 的左值,即調用函數可以修改 val 或取它的地址。grow()可以如下聲明返回一個引用: 
Matrix& grow( Matrix* p ) {
Matrix *res;
 
// 在動態儲存裝置中分配一個更大的 Matrix
// res 是指向新 Matrix 的指標
// 將*p 內容複寫到*res
return *res;
}
如果傳回值是一個大型類對象,用引用或指標傳回型別比按值返回類對象效率要高得多,在某些情況下編譯器自動將按值返迴轉換到按引用返回,該最佳化被稱為命名傳回值最佳化( named return value optimization )。

 

當聲明一個返回引用的函數時,程式員應當知道下面兩個易犯的錯誤: 

1.  返回一個指向局部對象的引用 局部對象的生命期隨函數的結束而結束,在函數結束後,該引用變成未定義記憶體的別名,例如:
// 問題: 返回一個指向局部對象的引用
Matrix& add( Matrix &m1, Matrix &m2 )
{
Matrix result;
 
if ( m1.isZero() )
  return m2;
if ( m2.isZero() )
  return m1;
 
// 將兩個 Matrix 對象的內容相加
// 喔! 返回之後 結果指向一個有問題的位置
return result;
}
在這種情況下,傳回型別應該被聲明為非參考型別,然後再在局部對象的生前拷貝局部變數 
Matrix add( ...

2.  函數返回一個左值 對傳回值的任何修改都將改變被返回的實際對象,例:
#include <vector>
 
int &get_val( vector<int> &vi, int ix ) {
return vi[ix];
}
 
int ai[4] = { 0, 1, 2, 3 };
 
vector<int> vec( ai, ai+4 );  // 將 ai 的 4 個元素複製到 vec

int main() {
// 將 vec[0] 增加到 1
get_val( vec,0 )++;
 
// ...
}


為防止對引用傳回值的無意修改,傳回值應該被聲明為const :
const int &get_val( ...

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.