[英]passing object by reference in C++
在C ++(也是C)中通過引用傳遞變量的常用方法如下:
void _someFunction(dataType *name){ // dataType e.g int,char,float etc.
/****
definition
*/
}
int main(){
dataType v;
_somefunction(&v); //address of variable v being passed
return 0;
}
但讓我吃驚,我通過引用傳遞對象時,對象的名稱本身就是目的(沒有注意到&
所需的符號),沒有的功能聲明中/定義*
被前面的參數所需的符號。 以下示例應明確說明:
// this
#include <iostream>
using namespace std;
class CDummy {
public:
int isitme (CDummy& param); //why not (CDummy* param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this) return true;
else return false;
}
int main () {
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) ) //why not isitme(&a)
cout << "yes, &a is b";
return 0;
}
我有問題理解為什么這個特殊的待遇是用課堂完成的。 即使是幾乎像一個類的結構也不會以這種方式使用。 對象名稱是否被視為數組的地址?
令你感到困惑的是,聲明為引用傳遞的函數(使用&
)不是使用實際地址調用的,即&a
。
簡單的答案是將函數聲明為pass-by-reference:
void foo(int& x);
是我們所需要的。 然后它會自動通過引用傳遞。
你現在調用這個函數是這樣的:
int y = 5;
foo(y);
和y
將通過引用傳遞。
你也可以這樣做(但為什么會這樣?咒語是: 盡可能使用引用,需要時使用指針 ):
#include <iostream>
using namespace std;
class CDummy {
public:
int isitme (CDummy* param);
};
int CDummy::isitme (CDummy* param)
{
if (param == this) return true;
else return false;
}
int main () {
CDummy a;
CDummy* b = &a; // assigning address of a to b
if ( b->isitme(&a) ) // Called with &a (address of a) instead of a
cout << "yes, &a is b";
return 0;
}
輸出:
yes, &a is b
引用實際上是一個指針,有足夠的糖使它味道很好......;)
但它也使用不同的指針語法,這使得使用引用比指針更容易。 因此,我們不需要&
在調用帶指針的函數時 - 編譯器會為您處理。 而且您不需要*
來獲取參考的內容。
要調用引用,別名是一個非常准確的描述 - 它是“同一事物的另一個名稱”。 所以,當a
被作為參考過去了,我們真的路過a
,而不是復制a
-它完成(內部)通過傳遞的地址a
,但你並不需要擔心它是如何工作[除非你正在編寫自己的編譯器,但是在編寫自己的編譯器時還需要了解許多其他有趣的事情,您不需要擔心何時編程]。
請注意,引用對int
或class
類型的工作方式相同。
在上述情況下通過引用傳遞只是實際對象的alias
。
您將使用不同的名稱來引用實際對象。
與pointer references
相比, references
提供了許多優點。
好吧,好吧,你似乎混淆了pass-by-reference和pass-by-value。 此外,C和C ++是不同的語言。 C不支持傳遞引用。
以下是兩個傳遞值的C ++示例 :
// ex.1
int add(int a, int b)
{
return a + b;
}
// ex.2
void add(int a, int b, int *result)
{
*result = a + b;
}
void main()
{
int result = 0;
// ex.1
result = add(2,2); // result will be 4 after call
// ex.2
add(2,3,&result); // result will be 5 after call
}
當調用ex.1時 ,常量2
和2
通過在堆棧上制作它們的本地副本而傳遞給函數。 當函數返回時,彈出堆棧,並且有效地消除了傳遞給堆棧上的函數的任何內容。
同樣的事情發生在ex.2中 ,除了這次,指向int
變量的指針也在棧上傳遞。 該函數使用此指針(它只是一個內存地址)來取消引用並更改該內存地址的值,以便“返回”結果。 由於函數需要一個內存地址作為參數,因此我們必須為它提供一個,我們通過在變量result
上使用&
“address-of”運算符來實現。
以下是兩個傳遞引用的C ++示例 :
// ex.3
int add(int &a, int &b)
{
return a+b;
}
// ex.4
void add(int &a, int &b, int &result)
{
result = a + b;
}
void main()
{
int result = 0;
// ex.3
result = add(2,2); // result = 2 after call
// ex.4
add(2,3,result); // result = 5 after call
}
這兩個函數與前兩個示例具有相同的最終結果,但不同之處在於它們的調用方式以及編譯器如何處理它們。
首先,讓我們了解pass-by-reference的工作原理。 在pass-by-reference中,通常編譯器實現將在最終可執行文件中使用“指針”變量來訪問引用的變量,(或者似乎是共識),但這不一定是真的。 從技術上講,編譯器可以簡單地直接替換引用變量的內存地址,我懷疑這比一般認為的更真實。 因此,在使用引用時,它實際上可以生成更高效的可執行文件,即使只是輕微的。
接下來,顯然在使用pass-by-reference時調用函數的方式與按值傳遞沒有什么不同,其效果是您可以直接訪問函數中的原始變量。 這通過隱藏來自調用者的實現細節而具有封裝的結果。 缺點是你不能改變傳入的參數而不改變函數之外的原始變量。 在您希望性能改進不需要復制大對象但不想修改原始對象的函數中,請在引用參數前加上const
。
最后,與指針變量不同,您無法在創建引用后更改引用,並且必須在創建時初始化它們。
希望我涵蓋了一切,這一切都是可以理解的。
我要補充的一件事是C中沒有引用。
其次,這是語言語法約定。 & - 是一個地址運算符,但它也意味着一個引用 - 所有這些都取決於美國的情況
如果有一些“引用”關鍵字而不是&你可以寫
int CDummy::isitme (reference CDummy param)
但這是C ++,我們應該接受它的優點和缺點......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.