關於傳值與傳引用的討論

2022-01-21 21:41:26 字數 1466 閱讀 2872

對於使用者自定義的型別來說,傳引用一般要比傳值高效。傳引用不需要經過物件過程,在《effective c++》中作者舉了個例子:

class base

class derive : public base

此刻我們擁有乙個派生類物件derive 。對derive傳值的結果是共需要進行六次的建構函式的呼叫:物件本身的建構函式,物件內部資料成員string的構造,物件基類部分的建構函式,物件基類資料成員string的構造。同樣的,待物件生命結束後,還要經歷6次析構函式的呼叫。而傳引用則不用進過如此多的構造與析構,甚至一次都不用。

對內建型別來說,傳值的效率往往要高於傳引用。內建型別包括了int,float ,double,指標型別等等。看下面的程式:

void f(int i)

void g(int & i)

int main()

當通過傳值呼叫函式f()時,其彙編**為:

當通過傳引用呼叫函式g()時,其彙編**為:

可以看到,傳引用比傳值多了一次定址操作,這是因為引用的實現往往基於指標,因此傳引用通常意味著真正傳遞的是指標。

總結:對內建型別來說,通常傳值更高效。

對用於自定義型別來所,傳值要經歷構造與析構過程,一般比較耗時。

傳值有時會引起物件的切割問題。就上面所示的兩個類,當我們定義如下函式並進行傳值呼叫時:

void func(base b)

int main()

編譯器將呼叫base類的複製建構函式來初始化b,初始化資料**於a,但構造結果是個base類物件:也就意味著a的特有部分的資料被切割掉了。在函式func中,b的行為是乙個base的行為而不是derive的行為。

通過傳引用,能夠避免切割的問題:

void func(base & b)

int main()

此時在函式func內,物件b實際型別為derive,通俗地將,b就是a。若希望在func中使用到實參的特性,傳引用能夠保證這一點。

如果你開啟stl中的原始碼,你會發現容器的iterator都是通過傳值形式傳參。在《effective c++》中指出,對於內建型別、stl 迭代器和 stl 仿函式,pass-by-value 也是可以的,一般沒有效能損失。在 x86-64 上,對於只有乙個 指標成員且沒有自定義複製建構函式的類,傳值是可以通過暫存器進行的,就像傳遞普通 int 和指標那樣。如上所示,傳值是可以比傳引用快的沒有,因為它少了一次解引用的操作。

(完)

關於傳值與傳引用的討論

對於使用者自定義的型別來說,傳引用一般要比傳值高效。傳引用不需要經過物件過程,在 effective c 中作者舉了個例子 class base class derive public base 此刻我們擁有乙個派生類物件derive 對derive傳值的結果是共需要進行六次的建構函式的呼叫 物件本...

傳值與傳引用

python的函式傳值和傳引用,和c c 語言是一樣的。在開始之前,我們有必要分清一下python的一些基礎概念。首先要說的是 變數 與 物件 在python中,型別屬於物件,變數是沒有型別的,這正是python的語言特性,也是吸引著很多pythoner的一點。所有的變數都可以理解是記憶體中乙個物件...

傳值 傳值引用

首先對傳值和傳引用要有個基本的概念 傳值 傳遞的是值的副本。方法中對副本的修改,不會影響到呼叫方。傳引用 傳遞的是引用的副本,共用乙個記憶體,會影響到呼叫方。此時,形參和實參指向同乙個記憶體位址。對引用副本本身 物件位址 的修改,如設定為null,重新指向其他物件,不會影響到呼叫方。直接上 更好的理...