[英]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 ++中的&
字符是雙重目的。 它可能意味着(至少)
您在函數簽名中引用的用法是#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 ++中, &
運算符意味着三件事之一 -
&
意思是按位AND。 另一種考慮引用的方法(雖然稍微不正確)是一個解引用指針的語法糖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.