傳參時,使用引用替換變數

2022-03-11 18:37:59 字數 1915 閱讀 2879

第乙個原因。。。

c++預設使用變數的方式傳遞物件。假如沒有另外指定,函式的引數都是以實參的副本為初值,而函式的返回值也是乙個復件。這些復件由物件的copy建構函式產出,這會讓值傳遞成為昂貴的操作。來乙個簡單的例子

class person

;class student:public person

;bool validatestudent(student s); //以值的方式接受學生

student plato; //柏拉圖

bool platoisok = validatestudent(plato); //呼叫函式

簡單地看,student的複製建構函式在傳入引數的時候會被呼叫,產生plato的副本初始化s,同樣,返回的時候將s銷毀,呼叫一次析構函式。也就是引數的傳遞成本是「一次student的複製建構函式與一次student的析構函式」。但是,讓我們解剖一下student。

乙個student中有4個string物件,2個繼承自person,2個student自己定義。而每個string也是乙個例項,意味著每個student初始化的時候string會被初始化時,就會初始化4個string,乙個person,每個student銷毀時,就會銷毀四個string,乙個person,所以,真正的呼叫這個函式的時候,引數傳遞的成本是「六次建構函式與六次析構函式」!!!

想到這些,頓時間十分堪憂我們程式的效能。解決的方法就是,使用引用代替普通的值傳遞。當然,假如需要保護形參,我們還可以加上const限制。

bool validatestudent(const student& s);

因為引用實際上是通過指標來實現的。引用一句話,"變數可以看成變數的別名」,也就是,使用引用是不會建立新的例項的。所以使用這種傳遞方式,效率高了很多,沒有任何建構函式與析構函式被呼叫,因為沒有建立任何新的例項。

第二個原因。。。

當然,使用引用的好處不僅僅是這些。使用引用的方式傳遞引數,還可以避免物件切割的問題。當派生類的物件傳遞給基類的物件時,呼叫的是基類的建構函式,派生類的那些特性將會被全部切割掉。試想一下有如下**。

class window

;class windowwithscrollbars:public window

;

當我們用乙個windowwithscrollbars型別的物件初始化乙個window型別的物件後,在window物件後呼叫display,一切不值得驚訝又讓人懊惱,我想顯示乙個視窗和內容但實際上它只給了我乙個視窗的名字。學習了虛函式之後,我們知道這可以通過指標來解決,同樣的,使用引用也能解決這個問題。

第三個原因。。。

編譯器對內建型別與使用者自定義型別的態度不太一致。比如,有些編譯器會將乙個double放入緩衝器中,但是卻拒絕將乙個只有double的class放入緩衝器中。而當我們使用引用的時候,引用是指標實現的,編譯器當然會將指標放入緩衝器中。

第四個原因。。。

你認為你的class很小,直接使用變數傳遞與使用引用傳遞沒有區別。但是,沒有人能夠保證class一直很小。就比如,class裡面只有乙個string,看起來真的很小,但不同的庫的string大小相差非常大,當你認為class很小的時候,它實際已經無限膨脹了。再比如,假如沒有使用引用,每次向class中增加內容的時候,你得小心翼翼增加的內容是否對你的效能會造成很大的影響。而假如你不希望有這種心理陰影,還是使用引用吧。

但是話說回來,又不是要求我們每時每刻都要使用引用來代替變數,比如,當我們使用stl庫的時候。stl庫習慣被設計成以變數的方式傳遞。比如傳遞其迭代器。所以,當我們使用stl庫的時候,我們直接使用變數傳遞引數會優於引用。

總結一下

使用引用傳遞引數會比變數更高效

使用引用傳遞引數可以避免物件切割的問題

不是所有的時候都使用引用比時候變數好,比如當使用stl庫或者函式物件的時候。

c 引用傳參和變數傳參區別

引用傳參會改變這個引數本身的值,而變數傳參不會改變引數本身的值。引用還有乙個好處就是在傳遞引數的時候不會產生過多的記憶體拷貝,這在傳遞結構體或者類的時候,可以節省很多時間和空間。include using namespace std void fun1 int int void fun2 int i...

python 函式傳參 傳參和傳引用

首先還是應該科普下函式引數傳遞機制,傳值和傳引用是什麼意思?函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在...

C 引用方式傳參,傳值方式傳參( )

1 引用方式傳參 引用相當於是外部變數的別名,實際操作的就是該變數,即在函式內對該變數進行修改的話,在外部該變數也會相應被修改。外部變數的值也會被修改 void changeref int ref 2 傳值方式傳參 實際上是複製了乙個外部變數的副本進入函式中,在函式內操作的為該副本,對該變數的修改並...