c++ 函數的值傳遞,引用傳遞 和 引用返回的探索

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

前言

C++的函數參數和返回分為按值傳遞和按引用傳遞,應用到類上面,會涉及到類的 賦值操作 復制函數 構造函數 析構函數

雖然java開發了兩年,但對我而言c++我還只是一個初學者.c++還有很多陌生的特性需要自己親自探索.這里用實際例子作為探索,不對之處望斧正:

由于基本類型和類在函數里的生命周期是相似的,這里以一個自定義類為例,一是為了方便觀察對象的地址,二是可以了解每一步會涉及到類的哪些生命周期:

類的定義

#include <iostream>using std::cout;
using std::endl;
using std::string;class A {
public:A() {cout << "構造函數:" << this << endl;}A(const A &input) {cout << "復制函數:" << this << endl;}// 復制直接返回 *this 本身A &operator=(const A &input) {cout << "賦值函數:" << this << endl;// this 其實是個新的內存空間,啥值都沒設置return *this;}~A() {cout << "析構函數:" << this << endl;}
};

值傳遞 和 返回值

我們定義一個值傳遞的函數,返回的也是值

A test1(A a) {cout << "test1函數體:&a=" << &a << endl;return a;
}

執行main函數如下

int main() {cout << "--- 對象創建 ---" << endl;A a;cout << "--- 函數調用 ---" << endl;A b = test1(a);cout << "--- 結束 ---" << endl;return 0;
}

執行結果

--- 對象創建 ---
構造函數:0x7fff5ed19768
--- 函數調用 ---
復制函數:0x7fff5ed19750
test1函數體:&a=0x7fff5ed19750
復制函數:0x7fff5ed19758
析構函數:0x7fff5ed19750
--- 結束 ---
析構函數:0x7fff5ed19758
析構函數:0x7fff5ed19768

由此可見,在函數的棧幀里,對入參a進行了一次復制(0x7fff5ed19750),而在返回棧幀里的input時,又會對函數結果復制生成一個臨時變量(0x7fff5ed19758),并回收棧幀里的input. 函數結束會把臨時變量返回給b,至此結束函數調用.也就是說,這里函數的入參和返回各涉及一次復制操作

函數入參和返回使用引用

我們對test1做出修改,將入參和返回變更為引用,如下

A &test1(A &a) {cout << "test1函數體:&a=" << &a << endl;return a;
}

將main中的b也變更為引用如下:

int main() {cout << "--- 對象創建 ---" << endl;A a;cout << "--- 函數調用 ---" << endl;A &b = test1(a);cout << "--- 結束 ---" << endl;return 0;
}

執行結果:

--- 對象創建 ---
構造函數:0x7fff56dd5768
--- 函數調用 ---
test1函數體:&a=0x7fff56dd5768
--- 結束 ---
析構函數:0x7fff56dd5768

因為是引用函數棧幀內并沒有進行任何復制操作

函數返回的臨時變量探索

如果函數不返回引用,或b不是引用,仍然會產生臨時變量

A test1(A &a) {cout << "test1函數體:&a=" << &a << endl;return a;
}
A& test2(A &a) {cout << "test2函數體:&a=" << &a << endl;return a;
}
int main() {cout << "--- 對象創建 ---" << endl;A a;cout << "--- 函數調用1 ---" << endl;A b1 = test1(a);cout << "--- 函數調用2 ---" << endl;A b2 = test2(a);cout << "--- 結束 ---" << endl;return 0;
}

返回結果如下

--- 對象創建 ---
構造函數:0x7fff5daae758
--- 函數調用1 ---
test1函數體:&a=0x7fff5daae758
復制函數:0x7fff5daae748
--- 函數調用2 ---
test2函數體:&a=0x7fff5daae758
復制函數:0x7fff5daae740
--- 結束 ---
析構函數:0x7fff5daae740
析構函數:0x7fff5daae748
析構函數:0x7fff5daae758

test1和test2的區別只在于返回結果是否為引用,但在棧幀外都產生了臨時變量

賦值操作探索

這里再對賦值做探索,這次把以上3中情況合在一起為例,如下

A &test1(A &a) {cout << "test1函數體:&a=" << &a << endl;return a;
}
A &test2(A a) {cout << "test2函數體:&a=" << &a << endl;return a;
}
A test3(A a) {cout << "test2函數體:&a=" << &a << endl;return a;
}
int main() {cout << "--- 對象創建 ---" << endl;A a;cout << "--- 函數調用1 ---" << endl;a = test1(a);cout << "--- 函數調用2 ---" << endl;a = test2(a);cout << "--- 函數調用3 ---" << endl;a = test3(a);cout << "--- 結束 ---" << endl;return 0;
}

輸出結果

--- 對象創建 ---
構造函數:0x7fff513b6748
--- 函數調用1 ---
test1函數體:&a=0x7fff513b6748
賦值函數:0x7fff513b6748
--- 函數調用2 ---
復制函數:0x7fff513b6738
test2函數體:&a=0x7fff513b6738
賦值函數:0x7fff513b6748
析構函數:0x7fff513b6738
--- 函數調用3 ---
復制函數:0x7fff513b6728
test2函數體:&a=0x7fff513b6728
復制函數:0x7fff513b6730
賦值函數:0x7fff513b6748
析構函數:0x7fff513b6730
析構函數:0x7fff513b6728
--- 結束 ---
析構函數:0x7fff513b6748
  • test1 相當于a=a;除了將值賦值給自己外棧幀沒有額外操作,這個很好理解
  • test2 對入參進行復制,并把復制的入參值賦值給a并在函數棧幀結束后回收入參
  • test3 比較復雜,會復制入參和臨時變量,并把臨時變量賦值給a,賦值結束后對入參和臨時變量進行回收

轉載于:https://my.oschina.net/tdONEmadao/blog/915677

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258521.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258521.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258521.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GCD的部分總結

GCD是基于C語言的底層API,用Block定義任務用起來非常靈活便捷. GCD的基本思想是就將操作放在隊列中去執行 (1)操作使用Blocks定義(2)隊列負責調度任務執行所在的線程以及具體的執行時間(3)隊列的特點是先進先出(FIFO)的&#xff0c;新添加至對列的操作都會排在隊尾關于多線程的…

將bgr彩色矩陣歸一化到0-255之間 【RGB image normalization】

參考下面文章&#xff0c;可以使用normalize 函數。 https://blog.csdn.net/kuweicai/article/details/78988886 對于彩色rgb圖像&#xff0c;也可以直接使用以上函數, 參考 https://devtalk.nvidia.com/default/topic/1042100/rgb-image-normalization/?offset8 image cv2…

多線程編程2-NSOperation

本文目錄 前言一、NSInvocationOperation二、NSBlockOperation三、NSOperation的其他用法四、自定義NSOperation回到頂部前言 1.上一講簡單介紹了NSThread的使用&#xff0c;雖然也可以實現多線程編程&#xff0c;但是需要我們去管理線程的生命周期&#xff0c;還要考慮線程同步…

python圖片顯示英文字符_python如何解析字符串中出現的英文人名?

這里有四個例子&#xff0c;結果來自google scholarstr1 "Jakes, William C., and Donald C. Cox. Microwave mobile communications. Wiley-IEEE Press, 1994."str2 "Schlegel, David J., Douglas P. Finkbeiner, and Marc Davis. \"Maps of dust infra…

閃回表操作語法+使用閃回刪除

閃回表操作語法 flashback table 【 schema.】 table_name to {【before drop 【rename to new_table_name】 】|【scn | timestamp 】】 expr 【enable | disable 】 triggers}: 參數說明&#xff1a; schema&#xff1a;用戶模式 before drop&#xff1a;表示恢復到刪除…

在現有的python環境下創建另一個python版本【親測有效】

比如&#xff0c;你現在的python環境是3.6&#xff0c;想要使用一個3.5&#xff0c;可以在anaconda環境下使用conda虛擬環境。 第一步&#xff1a; conda create -n py35 【創建Py35虛擬環境】 第二步&#xff1a; 進入環境 activate py35 第三步&#xff1a; 升級或者降…

時間戳

我發現&#xff0c;我在本站公布的文章&#xff0c;url 最后一段都是 134 開頭的一串數字。一開始并沒在意&#xff0c;僅僅想當然以為是程序隨機生成的。 昨天跟程序作者交談的過程中無意問起&#xff0c;他說這是代表時間的。剛才訪問 GoAgent 項目時發現&#xff0c;其作者 …

歐拉函數 - HDU1286

歐拉函數的作用&#xff1a; 有[1,2.....n]這樣一個集合&#xff0c;f(n)這個集合中與n互質的元素的個數。歐拉函數描述了一些列與這個f(n)有關的一些性質&#xff0c;如下&#xff1a; 1、令p為一個素數&#xff0c;n p ^ k&#xff0c;則 f(n) p ^ k - p ^ (k-1) 2、令m&…

其中一個頁簽慢_渭南提升一個大專學歷的有效方法

渭南提升一個大專學歷的有效方法&#xff0c;宏德教育&#xff0c;目前已形成以高等學歷教育為特色王牌&#xff0c;職稱考評、企業內訓為輔助的強力優勢品牌。渭南提升一個大專學歷的有效方法&#xff0c; 獲得發明專利或實用新型專利&#xff0c;且已實施取得效益。出版本專業…

《收集蘋果》 動態規劃入門

問題描寫敘述 平面上有N*M個格子&#xff0c;每一個格子中放著一定數量的蘋果。你從左上角的格子開始&#xff0c;每一步僅僅能向下走或是向右走&#xff0c;每次走到一個格子上就把格子里的蘋果收集起來&#xff0c;這樣下去&#xff0c;你最多能收集到多少個蘋果。 輸入&…

Xamarin XAML語言教程通過ProgressTo方法對進度條設置

2019獨角獸企業重金招聘Python工程師標準>>> Xamarin XAML語言教程通過ProgressTo方法對進度條設置 在ProgressBar中定義了一個ProgressTo方法&#xff0c;此方法也可以用來對進度條當前的進行進行設置&#xff0c;ProgressTo與Progress屬性的不同之處在于ProgressT…

Radar Installation

題目鏈接&#xff1a;http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id27586 題意&#xff1a; 在海岸線上擺放雷達并限定雷達覆蓋半徑d&#xff0c;再以海岸線為軸&#xff0c;給定海上島嶼坐標&#xff0c;求至少需要多少雷達可以覆蓋所以島嶼&#xff0c;如…

win7 + vs2015+ matlab2016a + python3.5安裝matcaffe cpu版本

參考&#xff1a; 1. caffe-windows直接安裝版---編譯后的Release 2.安裝Windows10 和環境下的caffe&#xff08;新版&#xff09; 3.win10vs2015編譯caffe的cpu debug版本、部署matcaffe 主要的方法參考文獻3. 當前caffe-windows僅支持python2.7和3.5 要注意的是&#…

python調用 matlab庫_python調用matlab的搜索結果-阿里云開發者社區

2018python技術問答集錦&#xff0c;希望能給喜歡python的同學一些幫助小編發現問答專區中有很多人在問關于python的問題&#xff0c;小編把這些問題匯總一下&#xff0c;希望能給喜歡python的大家一些啟示和幫助本帖不定期更新&#xff0c;喜歡的可以收藏哦python可能替代Java…

h5新特性

 CSDN博客 Gane_ChengHTML5新特性淺談 發表于2016/10/17 21:25:58 7809人閱讀 分類&#xff1a; 前端 轉載請注明出處&#xff1a; http://blog.csdn.net/gane_cheng/article/details/52819118 http://www.ganecheng.tech/blog/52819118.html &#xff08;瀏覽效果更好…

打勾顯示輸入的密碼 --EditText與setTransformationMethod

實現目標: 實現原理: 為CheckBox添加一個監聽器事件; 實現的源碼: package edu.cquptzx.showPassword; import android.app.Activity; import android.os.Bundle; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransforma…

mysql日期截取年月_攝影大賽丨“我遇見最美的光”第五屆全國醫務人員攝影大展 截稿日期2020年8月15日...

截稿日期2020年8月15日《“我遇見最美的光”第五屆全國醫務人員攝影大展》欣賞過山川壯麗&#xff0c;瞻仰過造化旖旎&#xff0c;敬重于生命偉大&#xff0c;感動于英雄凱旋……由《大眾攝影》主辦&#xff0c;正大天晴藥業集團股份有限公司、《中國衛生影像》雜志協辦的“我遇…

iframe子頁面內刷新父頁面中另一個iframe子頁面

框架頁面如下&#xff1a; <div id"aa" style"float: left; height: 500px; border-right-style: solid; border-right-color: #CCCCFF; border-right-width: 2px;"> <IFRAME id"tree" name"tree" src"/ScienProject…

Pytorch的C++接口實踐

Pytorch1.1版本已經提供了相對穩定的c接口&#xff0c;網上也有了眾多的資料供大家參考&#xff0c;進行c的接口的初步嘗試。 可以按照對應的選項下載&#xff0c;下面我們要說的是&#xff1a; 如何利用已經編譯好的官方libtorch庫和其他的opencv庫等聯合編寫應用&#xff1f…

一次慘痛的裝機經歷

最近不小心把我的聯想一體機電腦系統搞壞了&#xff0c;就不得不重裝系統&#xff0c;之前的系統是win7&#xff0c;于是開始的時候想著直接裝win10&#xff0c;升級一下系統。但是裝的過程中總是卡在了win10的正在準備系統中&#xff0c;進度環不轉了。后來轉了多次都不行&…