传递参数的方法 - 值与引用vs指针?

Sys*_*ata 3 c++

与其他编程语言相比,C++支持三种不同的参数传递:

  • 按价值
  • 引用
  • 按地址

我用C#编程了很长时间,从C#开发人员的角度来看,C++让我很困惑.在C#中它很容易.只需定义您想要的内容并返回结果,而C++则要复杂得多.有什么样时使用的指导方针by value,by reference,or by address

Cal*_*leb 9

传递参考和传递值之间的差异非常重要.当您通过值传递时,您实际上正在传递相关值的副本.无论函数发生什么,调用者中的值都将保持不变.所以,假设你有一个函数可以添加一个int并返回一个int:

int addOne(int theNumber)
{
    theNumber += 1;
    return theNumber;
}
Run Code Online (Sandbox Code Playgroud)

在这里,你正在经历价值.你这样称呼它:

int a = 10;
int b = addOne(a);    // b gets 11, but a remains the same
Run Code Online (Sandbox Code Playgroud)

如果你想通过引用传递,该函数将如下所示:

int addOne(int &theNumber)
{
    theNumber += 1;
    return theNumber;
}
Run Code Online (Sandbox Code Playgroud)

请注意,函数的主体保持不变.再次,你这样称呼它:

int a = 10;
int b = addOne(a);    // b gets 11, but this time a is also changed to 11.
Run Code Online (Sandbox Code Playgroud)

这里最大的区别是,你传递一个参考a.它实际上是一种隐式指针a,但您可以将其视为传递a自身.由于你传递的a不是副本的值a,a本身实际上会被函数改变.

第三种方式,传递地址,如下所示:

int addOne(int *theNumber)
{
    *theNumber = *theNumber + 1;
    return *theNumber;
}
Run Code Online (Sandbox Code Playgroud)

这与参考版本的功能相同,但这里的指针是显式的.你这样使用它:

int a = 10;
int b = addOne(&a);    // b gets 11, but this time a is also changed to 11.
Run Code Online (Sandbox Code Playgroud)

所以,在这种情况下,你明确地传递了地址a,也就是指向的地址a.如果你习惯于只通过价值,这应该是熟悉的.这是您通过aC和其他类似C语言的引用传递的方式.它工作正常,但你必须自己做所有的指针.C++增加了通过引用传递语言的概念,使这一切变得更加容易.

最后一种可能性是传递一个const引用,它避免复制值,但禁止在被调用函数中更改它.如果函数采用const引用,则可以将其视为不更改参数的承诺(并且它是编译器将强制执行的承诺).如果值超过几个字节,这将特别有用,因此如果可以,最好避免复制值.出于这个原因,对象通常由const引用传递.

因此,作为指南,当您不希望调用者传递的内容发生更改时,请传递值或const引用.如果您想要更改,请通过引用传递.除非你正在处理需要它的C库或其他代码,否则不要通过指针.