簡體   English   中英

在C ++函數簽名中使用&運算符

[英]Use of the & operator in C++ function signatures

我目前正在閱讀Accelerated C ++,我意識到我並不真正了解函數簽名的工作原理。

int* ptr=#

意味着ptr現在將地址保存為num,但這意味着什么?

void DoSomething(string& str)

從我的理解,這是一個變量的引用傳遞(這意味着傳遞地址),但當我這樣做

void DoSomething(string& str)
{
  string copy=str;
}

它創造的是str的副本。 我認為它會做的是引發錯誤,因為我正在嘗試分配一個指向變量的指針。

這里發生了什么? 在函數調用中使用*和&是什么意思?

引用不是指針,它們是不同的,盡管它們用於類似的目的。 您可以將引用視為另一個變量的別名,即具有相同地址的第二個變量。 它本身不包含地址,它只引用與初始化的變量相同的內存部分。

所以

string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s    

s = "Hello, world"; // corrected
assert( s == *p ); // this should be familiar to you, dereferencing a pointer
assert( s == r ); // this will always be true, they are twins, or the same thing rather

string copy1 = *p; // this is to make a copy using a pointer
string copy = r; // this is what you saw, hope now you understand it better.

C ++中的&字符是雙重目的。 它可能意味着(至少)

  1. 取一個值的地址
  2. 聲明對類型的引用

您在函數簽名中引用的用法是#2的實例。 參數string& str是對string實例的引用。 這不僅限於函數簽名,它也可以在方法體中發生。

void Example() {
  string s1 = "example";
  string& s2 = s1;  // s2 is now a reference to s1
}

我建議查看參考文獻中的C ++ FAQ條目,因為它是對它們的一個很好的介紹。

在進入Accelerated C ++的第10章之前,你不應該對指針有任何了解!

引用為其他地方存在的內容創建另一個名稱,別名。 而已。 沒有隱藏的指針或地址。 不要看幕后!

想想一個名叫羅伯特的人

guy   Robert;

有時你可能想叫他鮑勃

guy& Bob = Robert;

現在鮑勃和羅伯特都指的是同一個人。 你沒有得到他的地址(或電話號碼),只是同一件事的另一個名字。

在你的功能

void DoSomething(string& str)
{
  string copy=str;
}

它的工作原理完全相同, str是某個字符串的另一個名稱,存在於其他地方。

不要理會這種情況,只需將引用視為某個對象的名稱。 編譯器必須弄清楚如何連接名稱,您不必。

在分配變量的情況下(即int* ptr = &value ),使用&符號將返回變量的地址 (在本例中為value地址)。

在函數參數中,使用&符號表示您將訪問或引用傳遞給變量內存中的相同物理區域(如果不使用它,則會發送副本)。 如果您使用星號作為參數的一部分,那么您將指定傳遞變量指針,這將實現幾乎相同的事情。 這里的區別在於,使用&符號,您可以通過名稱直接訪問變量,但是如果傳遞指針,則必須遵循該指針來獲取和操作實際值:

void increase1(int &value) {
   value++;
}

void increase2(int *value) {
   (*value)++;
} 

void increase3(int value) {
   value++;
}

請注意, increase3對您傳遞的原始值沒有任何影響,因為只發送了一個副本:

int main() {
   int number = 5;
   increase1(number);
   increase2(&number);
   increase3(number);
   return 0;
}

3個函數調用結束時的number值為7,而不是8。

它是一個允許函數修改傳遞的字符串的引用,不像普通的字符串參數,其中修改不會影響傳遞給函數的字符串。

您經常會看到一個const string類型的參數,這是為了性能目的,因為內部的引用不會創建字符串的副本。

int* ptr=#

第一種情況:由於ptr是一個內存,它存儲一個變量的地址。 &運算符返回內存中num的地址。

void DoSomething(string& str)

第二種情況:&符號運算符用於表示變量是通過引用傳遞的,可以通過函數進行更改。

所以基本上&運算符有2個函數,具體取決於上下文。

雖然通過引用傳遞可以由編譯器通過將地址作為指針傳遞來實現,但在語義上它與地址或指針無關。 簡單來說,它只是變量的別名。

C ++有很多情況下語法在具有不同語義的不同上下文中重用,這是其中一種情況。

如果是:

int* ptr=#

您正在聲明一個名為ptr的變量,其類型為int * (int指針),並將其值設置為“變量num的地址”( &num )。 “addressof”運算符( & )返回一個指針。

如果是:

void DoSomething(string& str)

您聲明DoSomething()方法的第一個參數是“對字符串的引用”類型。 實際上,這是定義“傳遞引用”的C ++方式。

請注意,雖然&運算符在這些情況下的運算方式類似 ,但它的運算方式並不相同。 具體來說,當用作運算符時,您告訴編譯器獲取指定變量的地址; 當在方法簽名中使用時,您告訴編譯器該參數是引用。 並且還要注意,“作為引用的參數”位與具有指針的參數不同; 引用參數( & )會自動解除引用,並且對於存儲基礎數據的位置,方法永遠不會有任何接觸; 使用指針參數,您仍然通過引用傳遞,但是您正在暴露存儲變量的方法,並且如果方法無法取消引用(可能比您想象的更頻繁地發生),則可能會暴露問題。

你是不明確地從str復制構造copy 是的, str是一個引用,但這並不意味着你不能從中構造另一個對象。 在c ++中, &運算符意味着三件事之一 -

  1. 在定義普通引用變量時 ,可以為對象創建別名
  2. 當你在函數參數中使用它時,它會通過引用傳遞 - 你也在創建一個對象的別名 ,就像一個副本一樣。 在這種情況下,您沒有注意到任何差異,因為它基本上您傳遞給它的對象。 當你傳遞的對象包含指針等時,它確實有所不同。
  3. 最后一個(對你的案例來說無關緊要)和&意思是按位AND。

另一種考慮引用的方法(雖然稍微不正確)是一個解引用指針的語法糖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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