使用&;C+中的运算符+;函数签名 我现在正在阅读C++加速,我意识到我不太明白如何在函数签名中工作。p> int* ptr=#

使用&;C+中的运算符+;函数签名 我现在正在阅读C++加速,我意识到我不太明白如何在函数签名中工作。p> int* ptr=#,c++,pass-by-reference,C++,Pass By Reference,意味着ptr现在将地址保存到num,但这意味着什么 void DoSomething(string& str) 据我所知,这是一个通过引用传递的变量(这意味着传递地址),但当我这样做的时候 void DoSomething(string& str) { string copy=str; } 它创建的是str的一个副本。我认为它会引发一个错误,因为我试图将指针分配给一个变量 这里发生了什么?在函数调用中使用*和&的含义是什么? C++中的和字符是双重目的。这可能意味着(至

意味着ptr现在将地址保存到num,但这意味着什么

void DoSomething(string& str)
据我所知,这是一个通过引用传递的变量(这意味着传递地址),但当我这样做的时候

void DoSomething(string& str)
{
  string copy=str;
}
它创建的是str的一个副本。我认为它会引发一个错误,因为我试图将指针分配给一个变量


这里发生了什么?在函数调用中使用*和&的含义是什么?

C++中的<代码>和<代码>字符是双重目的。这可能意味着(至少)

  • 取一个值的地址
  • 声明对类型的引用
  • 您在函数签名中引用的用法是#2的一个实例。参数
    string&str
    是对
    string
    实例的引用。这不仅限于函数签名,还可以出现在方法体中

    void Example() {
      string s1 = "example";
      string& s2 = s1;  // s2 is now a reference to s1
    }
    
    我建议在引用中签出C++ FAQ条目,因为这是对它们的一个很好的介绍。p>

    这是一个允许函数修改传递字符串的引用,与普通字符串参数不同,普通字符串参数的修改不会影响传递给函数的字符串

    您经常会看到conststring类型的参数&这是出于性能目的,因为内部引用不会创建字符串的副本

    int* ptr=&num;
    
    第一种情况:因为ptr是一个内存,它存储一个变量的地址。&运算符返回内存中num的地址

    void DoSomething(string& str)
    
    第二种情况:符号和运算符用于表示变量是通过引用传递的,并且可以通过函数进行更改


    因此基本上,&运算符有两个函数,具体取决于上下文。

    虽然编译器可以通过将地址作为指针传递来实现引用传递,但从语义上讲,它与地址或指针无关。简单来说,它只是变量的别名


    C++有很多情况,语法在不同的上下文中以不同的语义被重用,这就是其中之一。

    您正在从
    str
    中莫名其妙地复制构建
    copy
    。是的,
    str
    是一个引用,但这并不意味着不能从它构造另一个对象。在C++中,<代码>和<代码>操作符是3种事物之一——

  • 定义正常引用变量时,为对象创建一个别名
  • 在函数paramater中使用它时,它是通过引用传递的——您还为对象创建了一个与副本对应的别名。在这种情况下,您没有注意到任何差异,因为它基本上就是您传递给它的对象。当您传递的对象包含指针等时,确实会产生影响
  • &
    的最后一个(与您的情况基本无关)含义是按位and

  • 考虑引用的另一种方式(尽管有点不正确)是对取消引用的指针进行语法分析。

    在分配变量(即,
    int*ptr=&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。

    引用是而不是指针,虽然它们的用途相似,但它们是不同的。 您可以将引用视为另一个变量的别名,即具有相同地址的第二个变量。它不包含地址本身,它只引用与初始化变量相同的内存部分

    所以

    在下列情况下:

    int* ptr=&num;
    
    void DoSomething(string& str)
    
    您正在声明一个名为
    ptr
    的变量,其类型为
    int*
    (int指针),并将其值设置为“变量num的地址”(
    &num
    )。“addressof”运算符(
    &
    )返回指针

    在下列情况下:

    int* ptr=&num;
    
    void DoSomething(string& str)
    
    您将DoSomething()方法的第一个参数声明为“reference to string”类型。有效地,这是C++定义“通过引用”的方式。
    请注意,在这些情况下,
    &
    运算符的操作方式与类似,但其操作方式不同。具体来说,当用作运算符时,您告诉编译器获取指定变量的地址;在方法签名中使用时,您告诉编译器参数是引用。还要注意的是,“参数作为引用”位不同于具有作为指针的参数;引用参数(
    &
    )会自动取消引用,并且对于底层数据的存储位置,该方法不会有任何暴露;对于指针参数,您仍然通过引用进行传递,但是您将暴露给存储变量的方法,并且如果该方法无法执行解引用(这种情况发生的频率比您想象的要高),则可能会暴露问题

    直到你进入加速C++第10章,你不应该知道指针<强>任何<强>。p> 推荐人
    guy& Bob = Robert;
    
    void DoSomething(string& str)
    {
      string copy=str;
    }