繁体   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