類物件的「傳值」與「傳引用」

2021-06-05 07:10:16 字數 1293 閱讀 6957

"傳值"就是通過值來傳遞乙個物件,這個過程需要拷貝建構函式來進行。而"傳引用"實質上就是一種指標傳遞。兩種傳遞方式在使用上存在效率問題和"切割"問題。

1、效率

而前所述,"傳值"需要呼叫拷貝建構函式。例如:

class ctest

ctest(const ctest& ref)

~ctest()

ctest fun(ctest obj)};

void main()

上述**的輸出結果是:

ctest::ctest()

ctest::ctest()

ctest::ctest(const ctest& ref)

ctest::ctest(const ctest& ref)

ctest::~ctest()

ctest::~ctest()

ctest::~ctest()

ctest::~ctest()

在呼叫fun()成員函式時,傳入實參呼叫一次拷貝建構函式,返回值呼叫一次拷貝建構函式。也就是說:呼叫一次fun()成員函式,需要呼叫兩次拷貝建構函式和兩次析構函式。如此昂貴的開銷不得不讓人有所警惕。

定義乙個物件的引用就是給物件起個別名,無需呼叫拷貝建構函式。因而,將fun()成員函式的形參和返回值改為"傳引用",能避免呼叫拷貝建構函式和析構函式。這社會,能節省開銷就要節省開銷。

*注:在上述例子中,將返回值改為"傳引用"只是為了說明問題,其實返回區域性物件的引用,其後果是難以**的。

2、切割問題

當乙個派生類的物件作為基類物件被傳遞時,它(派生類物件)的作為派生類所具有的行為特性會被「切割」掉,從而變成了乙個簡單的基類物件。例如:

class cbase

}; class cderive : public cbase

}; void fun(cbase objcbase)

這時,如果執行下面語句:

cderive objcderive;

fun(objcderive);

很抱歉,這時執行的是cbase::display()。這就是切割問題。其實也不難理解:fun()申請的是cbase物件的空間buf1,這時跑來的卻是cderive物件的空間buf2,buf1可裝不下buf2,不好意思,buf2中除buf1以外的空間必須切割掉。這種切割問題很明顯違反了程式設計師的意圖。

如果將fun()的形參改為"傳引用",問題就回到多型性上了。"傳引用"實質就是一種位址傳遞,這時候基類的指標指向派生類,因而呼叫的虛函式就是派生類的虛函式。這時程式設計師的意圖得到了表達。

傳值與傳引用

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

傳值 傳值引用

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

PHP的傳值與引用,php 傳值與傳引用的區別詳解

在php中傳值與傳引用對於我們來講是有比較大的區別的乙個引用可以呼叫記憶體位址賦值了,這樣只要記憶體位址中內容變化而賦值的變數也就變化了,付值只是把記憶體中值給其它變數而己。傳值 函式引數壓棧的是引數的副本。任何的修改是在副本上作用,沒有作用在原來的變數上。傳引用 壓棧的是引用的副本。由於引用是指向...