【问题标题】:Does passing parameters by reference in C++ have to be manual?在 C++ 中通过引用传递参数是否必须是手动的?
【发布时间】:2013-01-18 04:19:15
【问题描述】:

我正在学习 C++,并且正在阅读 book on it,我在其中遇到了这个问题:

struct Vector{
   int size;
   double* elem;
}

void vector_init(Vector& v, int s){
   v.size = s;
   v.elem = new double[s];
}

那么在这里,void vector_init(Vector v, int s),如果没有引用运算符,会错吗?在传递对象、结构、数组或其他任何东西作为参数时,我是否必须使用 & 手动通过引用传递?还有其他方法可以做到这一点吗?比如void vector_init(Vector *v, int s)

感谢任何帮助。

【问题讨论】:

  • 提示:不要在 C++ 中使用指针。总有更好的选择。
  • @David 并非总是如此;非拥有指针最好表示为原始指针(当您不能使用引用时,例如需要可分配的类的成员(或成员本身需要可分配)或可以为空时) .
  • 在 C++ 中可以完全避免使用指针吗?
  • @rgamber 取决于您需要做什么。大多数情况下它们都可以,尤其是在您编写应用程序代码时。但有时不会。

标签: c++ parameter-passing pass-by-reference


【解决方案1】:

没有“引用运算符”。

& 声明符只会添加到您希望通过引用传递的函数参数中。传递引用参数看起来与传递值相同。

【讨论】:

    【解决方案2】:

    如果没有引用运算符,void vector_init(Vector v, int s) 会出错吗?

    如果您不通过引用传递v,则在进入函数vector_init 并对该副本进行操作时,将生成v 的副本。在vector_init 返回后,临时副本将被销毁,因此vector_init 对您原来的v 没有影响。要对原始v 进行操作,您需要通过引用传递v(与其他类型相同)。

    还有其他方法可以做到这一点吗?比如void vector_init(Vector *v, int s)

    与通过指针传递相比,通过引用传递是更好的选择。

    【讨论】:

    • 哦。因此,当我执行 Vector v 时,它传递的是引用的值,而不是引用本身,因此是 &。我说的对吗?
    • Vector v 正在传递v 的值。 Vector& v' 正在传递 v 的引用。
    • 哦..我明白了,所以 v 的整个值作为结构将被传递。所以更改将发生在副本上,原始 v 将保持不变。谢谢..
    【解决方案3】:

    实际上通过引用 (void vector_init(Vector &v, int s)) 或通过指针 void vector_init(Vector *v, int s) 传递值的含义基本相同。

    主要区别在于,当您通过引用传递时,您必须传递有效参数(NULL 不起作用),而当您通过指针传递时,您必须显式地将参数转换为指针(虽然这是通过引用传递时自动完成)

    当你像在 void vector_init(Vector v, int s) 中那样传递一些 按值 时,情况就不同了:参数是通过复制构造函数复制的,并且在函数范围内进行的每个修改都是本地副本的本地副本参数,您不能通过值传递修改原始参数。您实际上并没有传递变量,而是传递了它的副本。

    这甚至意味着,如果参数是大型类或结构或具有昂贵的复制构造函数,那么也会出现性能问题。

    【讨论】:

    • 按值传递的参数并不总是被复制,它也可以移动。
    • @SethCarnegie:难道不能只使用右值引用吗?
    • 不,右值引用只是一个引用,而不是一个副本。当使用右值引用(并且有一个移动构造函数)初始化一个值时,就会发生移动。编译器会在可能的情况下自动将 xvalue 转换为 rvalue 引用。还有一个更好的选择,可以省略复制/移动(编译器优化),甚至不会发生移动。
    • @SethCarnegie:我刚刚发现这个关于该主题的有用链接:cpp-next.com/archive/2009/08/want-speed-pass-by-value,看起来很有趣,谢谢你指出这一点。
    猜你喜欢
    • 2016-07-21
    • 2021-05-02
    • 2014-05-29
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 2014-07-26
    相关资源
    最近更新 更多