在 C++ 函数签名中使用 & 运算符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6877052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use of the & operator in C++ function signatures
提问by Ziv
I'm currently reading through Accelerated C++ and I realized I don't really understand how & works in function signatures.
我目前正在阅读 Accelerated C++,但我意识到我并不真正了解函数签名中的 & 工作原理。
int* ptr=#
means that ptr now holds the address to num, but what does that mean?
意味着 ptr 现在持有 num 的地址,但这意味着什么?
void DoSomething(string& str)
from what I understand that is a pass by reference of a variable (which means passing the address) but when I do
据我所知,这是一个变量的引用传递(这意味着传递地址)但是当我这样做时
void DoSomething(string& str)
{
string copy=str;
}
what it creates is a copy of str. What I thought it would do is raise an error since I'm trying to assign a pointer to a variable.
它创建的是 str 的副本。我认为它会引发错误,因为我试图将指针分配给变量。
What is happening here? And what is the meaning of using * and & in function calls?
这里发生了什么?在函数调用中使用 * 和 & 是什么意思?
回答by unkulunkulu
A reference is nota pointer, they're different although they serve similar purpose. You can think of a reference as an alias to another variable, i.e. the second variable having the same address. It doesn't contain address itself, it just referencesthe same portion of memory as the variable it's initialized from.
引用不是指针,虽然它们的用途相似,但它们是不同的。您可以将引用视为另一个变量的别名,即具有相同地址的第二个变量。它不包含地址本身,它只是引用与它初始化的变量相同的内存部分。
So
所以
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.
回答by JaredPar
The &
character in C++ is dual purpose. It can mean (at least)
&
C++ 中的字符具有双重用途。它可能意味着(至少)
- Take the address of a value
- Declare a reference to a type
- 取值的地址
- 声明一个类型的引用
The use you're referring to in the function signature is an instance of #2. The parameter string& str
is a reference to a string
instance. This is not just limited to function signatures, it can occur in method bodies as well.
您在函数签名中所指的用法是#2 的一个实例。该参数string& str
是对string
实例的引用。这不仅限于函数签名,它也可以出现在方法体中。
void Example() {
string s1 = "example";
string& s2 = s1; // s2 is now a reference to s1
}
I would recommend checking out the C++ FAQ entry on references as it's a good introduction to them.
我建议查看有关参考的 C++ FAQ 条目,因为它是对它们的一个很好的介绍。
回答by Bo Persson
You shouldn't know anythingabout pointers until you get to chapter 10 of Accelerated C++ !
在阅读 Accelerated C++ 的第 10 章之前,您不应该对指针有任何了解!
A reference creates another name, an alias, for something that exists elsewhere. That's it. There are no hidden pointers or addresses involved. Don't look behind the curtain!
引用为其他地方存在的事物创建另一个名称、别名。就是这样。不涉及隐藏的指针或地址。不要看窗帘后面!
Think of a guy named Robert
想想一个叫罗伯特的人
guy Robert;
Sometimes you may want to call him Bob
有时你可能想叫他鲍勃
guy& Bob = Robert;
Now Bob and Robert both refer to the same guy. You don't get his address (or phone number), just another name for the same thing.
现在鲍勃和罗伯特都指的是同一个人。你没有他的地址(或电话号码),只是同一件事的另一个名字。
In your function
在你的函数中
void DoSomething(string& str)
{
? string copy=str;
}
it works exactly the same, str
is another name for some string that exists somewhere else.
它的工作原理完全相同,str
是存在于其他地方的某个字符串的另一个名称。
Don't bother with how that happens, just think of a reference as a name for some object. The compiler has to figure out how to connect the names, you don't have to.
不要担心这是如何发生的,只需将引用视为某个对象的名称即可。编译器必须弄清楚如何连接名称,您不必这样做。
回答by Manny D
In the case of assigning variables (ie, int* ptr = &value
), using the ampersand will return the addressof your variable (in this case, address of value
).
在分配变量的情况下(即int* ptr = &value
),使用&符号将返回变量的地址(在这种情况下为 的地址value
)。
In function parameters, using the ampersand means you're passing access, or reference, to the same physical area in memory of the variable (if you don't use it, a copy is sent instead). If you use an asterisk as part of the parameter, you're specifying that you're passing a variable pointer, which will achieve almost the same thing. The difference here is that with an ampersand you'll have direct access to the variable via the name, but if you pass a pointer, you'll have to deferencethat pointer to get and manipulate the actual value:
在函数参数中,使用&符号意味着您正在传递对变量内存中相同物理区域的访问或引用(如果您不使用它,则会发送副本)。如果您使用星号作为参数的一部分,那么您指定的是您正在传递一个变量指针,这将实现几乎相同的效果。这里的区别在于,使用 & 符号可以通过名称直接访问变量,但是如果传递指针,则必须遵循该指针来获取和操作实际值:
void increase1(int &value) {
value++;
}
void increase2(int *value) {
(*value)++;
}
void increase3(int value) {
value++;
}
Note that increase3
does nothing to the original value you pass it because only a copy is sent:
请注意,increase3
它对传递给它的原始值没有任何影响,因为只发送了一个副本:
int main() {
int number = 5;
increase1(number);
increase2(&number);
increase3(number);
return 0;
}
The value of number
at the end of the 3 function calls is 7, not 8.
number
3 次函数调用结束时的值是 7,而不是 8。
回答by pezcode
It's a reference which allows the function to modify the passed string, unlike a normal string parameter where modification would not affect the string passed to the function.
它是一个引用,它允许函数修改传递的字符串,不像普通的字符串参数,修改不会影响传递给函数的字符串。
You will often see a parameter of type const string& which is done for performance purposes as a reference internally doesn't create a copy of the string.
您经常会看到一个 const string& 类型的参数,它是出于性能目的而完成的,因为内部引用不会创建字符串的副本。
回答by Pepe
int* ptr=#
1st case: Since ptr is a memory and it stores the address of a variable. The & operator returns the address of num in memory.
第一种情况:由于 ptr 是内存,它存储变量的地址。& 运算符返回内存中 num 的地址。
void DoSomething(string& str)
2nd case: The ampersand operator is used to show that the variable is being passed by reference and can be changed by the function.
第二种情况:与号运算符用于表示变量是通过引用传递的,并且可以由函数更改。
So Basically the & operator has 2 functions depending on the context.
所以基本上 & 运算符根据上下文有 2 个函数。
回答by jk.
While pass by reference may be implemented by the compiler by passing the address as a pointer, semantically it has nothing to do with addresses or pointers. in simple terms it is merely an alias for a variable.
虽然编译器可以通过将地址作为指针传递来实现按引用传递,但在语义上它与地址或指针无关。简单来说,它只是一个变量的别名。
C++ has a lot of cases where syntax is reused in different contexts with different semantics and this is one of those cases.
C++ 有很多语法在具有不同语义的不同上下文中重用的情况,这就是其中一种情况。
回答by Paul Sonier
In the case of:
如果是:
int* ptr=#
you are declaring a variable named ptr
with a type of an int *
(int pointer), and setting its value to the "address of the variable num" (&num
). The "addressof" operator (&
) returns a pointer.
您正在声明一个以(int 指针)ptr
类型命名的变量int *
,并将其值设置为“变量 num 的地址”( &num
)。“addressof”运算符 ( &
) 返回一个指针。
In the case of:
如果是:
void DoSomething(string& str)
you are declaring the first parameter of the DoSomething() method to be of type "reference to string". Effectively, this is the C++ way of defining "pass-by-reference".
您将 DoSomething() 方法的第一个参数声明为“对字符串的引用”类型。实际上,这是定义“引用传递”的 C++ 方式。
Note that while the &
operator operates similarlyin these cases, it's not acting in the same way. Specifically, when used as an operator, you're telling the compiler to take the address of the variable specified; when used in a method signature, you're telling the compiler that the argument is a reference. And note as well, that the "argument as a reference" bit is different from having an argument that is a pointer; the reference argument (&
) gets dereferenced automatically, and there's never any exposure to the method as to where the underlying data is stored; with a pointer argument, you're still passing by reference, but you're exposing to the method where the variable is stored, and potentially exposing problems if the method fails to do a dereference (which happens more often than you might think).
请注意,虽然&
操作符在这些情况下的操作类似,但它的操作方式并不相同。具体来说,当用作运算符时,您是在告诉编译器获取指定变量的地址;在方法签名中使用时,您是在告诉编译器该参数是一个引用。还要注意,“作为引用的参数”位与作为指针的参数不同;参考参数(&
) 自动取消引用,并且永远不会暴露于该方法的底层数据存储位置;使用指针参数,您仍然是通过引用传递,但是您将暴露给存储变量的方法,并且如果该方法无法取消引用(这种情况发生的频率比您想象的要高),则可能会暴露问题。
回答by Seb Holzapfel
You're inexplicitly copy-constructing copy
from str
. Yes, str
is a reference, but that doesn't mean you can't construct another object from it. In c++, the &
operator means one of 3 things -
您正在copy
从str
. 是的,str
是一个引用,但这并不意味着你不能从它构造另一个对象。在 C++ 中,&
运算符意味着三件事之一 -
- When you're defining a normal reference variable, you create an aliasfor an object.
- When you use it in a function paramater, it is passed by reference- you are also making an aliasof an object, as apposed to a copy. You don't notice any difference in this case, because it basically isthe object you passed to it. It doesmake a difference when the objects you pass contain pointers etc.
- The last (and mostly irrelevent to your case) meaning of
&
is the bitwise AND.
- 当你定义一个普通的引用变量时,你为一个对象创建了一个别名。
- 当您在函数参数中使用它时,它是通过引用传递的- 您还创建了一个对象的别名,与副本并列。在这种情况下,您不会注意到任何区别,因为它基本上是您传递给它的对象。当您传递的对象包含指针等时,它确实会有所不同。
- 最后一个(并且大部分与您的情况无关)的含义
&
是按位与。
Another way to think about a reference (albeit slightly incorrect) is syntactic sugar for a dereferenced pointer.
考虑引用的另一种方式(尽管有点不正确)是解引用指针的语法糖。