簡體   English   中英

在C ++中通過引用傳遞對象

[英]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 (&param == 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 ,但你並不需要擔心它是如何工作[除非你正在編寫自己的編譯器,但是在編寫自己的編譯器時還需要​​了解許多其他有趣的事情,您不需要擔心何時編程]。

請注意,引用對intclass類型的工作方式相同。

在上述情況下通過引用傳遞只是實際對象的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時 ,常量22通過在堆棧上制作它們的本地副本而傳遞給函數。 當函數返回時,彈出堆棧,並且有效地消除了傳遞給堆棧上的函數的任何內容。

同樣的事情發生在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM