简体   繁体   English

在C ++函数签名中使用&运算符

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

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. 它创造的是str的副本。 What I thought it would do is raise an error since I'm trying to assign a pointer to a variable. 我认为它会做的是引发错误,因为我正在尝试分配一个指向变量的指针。

What is happening here? 这里发生了什么? And what is the meaning of using * and & in function calls? 在函数调用中使用*和&是什么意思?

A reference is not a pointer, they're different although they serve similar purpose. 引用不是指针,它们是不同的,尽管它们用于类似的目的。 You can think of a reference as an alias to another variable, ie the second variable having the same address. 您可以将引用视为另一个变量的别名,即具有相同地址的第二个变量。 It doesn't contain address itself, it just references the 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.

The & character in C++ is dual purpose. C ++中的&字符是双重目的。 It can mean (at least) 它可能意味着(至少)

  1. Take the address of a value 取一个值的地址
  2. Declare a reference to a type 声明对类型的引用

The use you're referring to in the function signature is an instance of #2. 您在函数签名中引用的用法是#2的实例。 The parameter string& str is a reference to a string instance. 参数string& str是对string实例的引用。 This is not just limited to function signatures, it can occur in method bodies as well. 这不仅限于函数签名,它也可以在方法体中发生。

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条目,因为它是对它们的一个很好的介绍。

You shouldn't know anything about 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. 编译器必须弄清楚如何连接名称,您不必。

In the case of assigning variables (ie, int* ptr = &value ), using the ampersand will return the address of 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 deference that 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. 3个函数调用结束时的number值为7,而不是8。

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类型的参数,这是为了性能目的,因为内部的引用不会创建字符串的副本。

int* ptr=#

1st case: Since ptr is a memory and it stores the address of a variable. 第一种情况:由于ptr是一个内存,它存储一个变量的地址。 The & operator returns the address of num in memory. &运算符返回内存中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个函数,具体取决于上下文。

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 ++有很多情况下语法在具有不同语义的不同上下文中重用,这是其中一种情况。

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 ). 您正在声明一个名为ptr的变量,其类型为int * (int指针),并将其值设置为“变量num的地址”( &num )。 The "addressof" operator ( & ) returns a pointer. “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". 您声明DoSomething()方法的第一个参数是“对字符串的引用”类型。 Effectively, this is the C++ way of defining "pass-by-reference". 实际上,这是定义“传递引用”的C ++方式。

Note that while the & operator operates similarly in 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). 使用指针参数,您仍然通过引用传递,但是您正在暴露存储变量的方法,并且如果方法无法取消引用(可能比您想象的更频繁地发生),则可能会暴露问题。

You're inexplicitly copy-constructing copy from str . 你是不明确地从str复制构造copy Yes, str is a reference, but that doesn't mean you can't construct another object from it. 是的, str是一个引用,但这并不意味着你不能从中构造另一个对象。 In c++, the & operator means one of 3 things - 在c ++中, &运算符意味着三件事之一 -

  1. When you're defining a normal reference variable , you create an alias for an object. 在定义普通引用变量时 ,可以为对象创建别名
  2. When you use it in a function paramater, it is passed by reference - you are also making an alias of an object, as apposed to a copy. 当你在函数参数中使用它时,它会通过引用传递 - 你也在创建一个对象的别名 ,就像一个副本一样。 You don't notice any difference in this case, because it basically is the object you passed to it. 在这种情况下,您没有注意到任何差异,因为它基本上您传递给它的对象。 It does make a difference when the objects you pass contain pointers etc. 当你传递的对象包含指针等时,它确实有所不同。
  3. The last (and mostly irrelevent to your case) meaning of & is the bitwise AND. 最后一个(对你的案例来说无关紧要)和&意思是按位AND。

Another way to think about a reference (albeit slightly incorrect) is syntactic sugar for a dereferenced pointer. 另一种考虑引用的方法(虽然稍微不正确)是一个解引用指针的语法糖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM