C++:按值传递对象的原因

cls*_*udt 4 c++ java oop

在Java中,包含适当对象的所有变量实际上都是引用(即指针).因此,使用这些对象作为参数的方法调用始终是"通过引用".调用修改对象状态的方法也会影响原始对象(在调用者端).

C++是不同的:这里的参数可以通过值传递或通过引用传递.在通过值传递的对象上调用mutator方法会使原始对象不受影响.(我想按值调用会创建对象的本地副本).

所以我对此的第一反应 - 从Java到C++ - 是:当使用对象作为参数时,总是使用指针.这给了我从Java期望的行为.

但是,如果一个人不需要修改方法体中的对象,也可以使用"按值调用".是否有人想要这样做?

Pra*_*ian 12

使用对象作为参数时,总是使用指针

不,在C++中总是通过引用传递,除非您的函数可以nullptr作为有效参数调用.如果函数不需要修改参数,则按const引用传递.

按值传递参数有几种用途.

如果您的函数需要创建参数的副本,最好通过传递值而不是在函数内创建副本来创建此副本.例如:

void foo( widget const& w )
{
  widget temp( w );
  // do something with temp
}
Run Code Online (Sandbox Code Playgroud)

而是使用

void foo( widget w )  // copy is made here
{
  // operate on w itself
}
Run Code Online (Sandbox Code Playgroud)

这样做的好处是允许编译器尽可能移动 widget,这通常比创建副本更有效.

  • @Robinson [这里](http://stackoverflow.com/a/3109981/241631)一个很好的答案描述移动语义 (2认同)

Luc*_*ore 9

你错了,你应该通过指针传递.如果你想通过引用传递,那么......只需通过引用传递:

void foo(int& x)
{
   x = 3;
}

int main()
{
   int a = 0;
   foo(a);
   assert( a == 3 );
}
Run Code Online (Sandbox Code Playgroud)

另请注意,传递值可确保在调用的上下文中无法更改您的变量.虽然通过const参考传递...

  • @Adam:使用address-of来表达可变性是C设计API的工件.C++方式是使用reference和const引用.我在每次代码审查中都积极地询问我的同行,我看到他们使用`*`来使用`&`,除非是一个可以接受`NULL'的可选参数 (4认同)
  • @AdamLiss不,你不是要求任何麻烦,除非你和像你这样的开发人员一起工作,他们在可变引用和指针之间进行了如此大的区分.`foo(int&)`清楚地表明`foo`可以修改调用者上下文中的参数.唯一`foo(int*)`告诉我的是我可以用`nullptr`作为参数调用`foo`,函数*应该*处理它.但是,如果该功能没有检查你手上有错误的程序. (3认同)
  • 这也是另一种方式:引用不能为null.这种情况是我在引用上选择指针的唯一原因. (2认同)
  • @AdamLiss我不同意见.签名清楚地表示"这个值可以被修改"与指针等效的一样多. (2认同)
  • @KeithRandall如何在不知道原型的情况下调用函数? (2认同)
  • @MartinJames我们可以做到这一点,或者你实际上可以从这个对话中获取一些东西,而不是坚持你是对的,只是去学习一个基本的**C++概念,这样它就不会显得如此奇怪和混淆您.这只是一个友好的建议. (2认同)