Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 按值、常量值、引用或常量引用传递非POD类型_C++_Constants_Pass By Reference_Pass By Value - Fatal编程技术网

C++ 按值、常量值、引用或常量引用传递非POD类型

C++ 按值、常量值、引用或常量引用传递非POD类型,c++,constants,pass-by-reference,pass-by-value,C++,Constants,Pass By Reference,Pass By Value,我需要把一个非POD类型传递给C++函数。 我想修改该函数内部的值,但我不希望该更改在该函数外部可见 void myFunction (const NonSimpleObject &foo) { NonSimpleObject foo_internal = ~foo; } 我的第一个选择是通过值传递,这将创建一个副本 void myFunction (NonSimpleObject foo) { foo = ~foo; } 我也可以通过引用传递,这在函数调用期间更

我需要把一个非POD类型传递给C++函数。 我想修改该函数内部的值,但我不希望该更改在该函数外部可见

void myFunction (const NonSimpleObject &foo) {
  NonSimpleObject foo_internal = ~foo;      
}
我的第一个选择是通过值传递,这将创建一个副本

void myFunction (NonSimpleObject foo) {
  foo = ~foo;
}
我也可以通过引用传递,这在函数调用期间更快,但我需要在内部创建一个副本,以不影响外部值

void myFunction (NonSimpleObject &foo) {
  NonSimpleObject foo_internal = ~foo;      
}
为了向调用者发出不修改外部值的信号,我想包括一个常量限定符。这在按值调用时当然是隐式的,但我希望更详细一些。但是传递一个const值将迫使我在内部创建第二个副本来修改该值,这在某种程度上与最初使用const限定符的目的相反

void myFunction (const NonSimpleObject foo) {
  NonSimpleObject foo_internal = ~foo;
}
传递const引用将向调用方发出信号,表明外部值没有更改,并且只需要函数内部的一个副本

void myFunction (const NonSimpleObject &foo) {
  NonSimpleObject foo_internal = ~foo;      
}
哪一个最适合我的目的(性能好,对调用者来说冗长),其优点/缺点是什么


这也归结为以下问题:在函数内部复制而不是在参数传递过程中复制有什么好处吗?反之亦然?

只需按值传递即可:

  • 它创建了一个副本(并使您无需为其编写任何代码,即显式副本)
  • 关于您所做操作的语义问题:通过值传递的参数向调用代码表明,您没有修改函数中的对象,您创建了它的副本,并且原始对象将保持不变<代码>常量是传递给函数的实际对象(即带引用的对象),并且您不希望修改它(例如只是“偷看”)时,最好使用它
  • 按引用传递需要手动创建一个副本,这是通过按值传递来完成的
所以,这样:

void myFunction (NonSimpleObject foo) {
   //modify foo here
}
第一种情况(
voidmyfunction(nonsimpleobjectfoo)
)将创建两个对象。第一个对象是
foo
,第二个对象是
foo\u internal

第二种情况(
void myFunction(const NonSimpleObject&foo)
)将只创建一个对象,即
foo\u internal

因此,第二种情况更好

在函数内部复制而不是在参数传递过程中复制有什么好处吗?反之亦然


如果要使用创建的对象,请复制它。您没有显示足够的代码来判断是否需要该副本。就目前而言,我会说使用常量引用。

如果您需要一个本地对象,那么按值传递是最好的。如果参数是临时的或显式移动的,这将启用移动语义,从而避免不必要的复制

通过引用传递将强制复制,无论是否需要。如果引用不是常量,则参数不能是临时变量。通过值接受一个
const
对象,然后复制它是很奇怪的

(请注意,在您的特定示例中,您不需要本地副本,只需要将运算符应用于参数的结果;因此,
const
引用可能更合适。)

“我想修改该函数内的值,但我不希望该更改在该函数外可见。”

那么您的意思是更改对象的本地副本。(我不认为您指的是允许您更改对象的私有数据的
friend
-函数。)

因此,您需要按值传递,最干净的解决方案是1。(而不是通过引用,然后在本地副本内制作(您的2.0解决方案))

这向用户发出信号,表示传递的对象将不会更改(仅更改其本地副本,但这正是您想要的)。通过值将其传递给const(您的3.solution)略有不同:您不仅向用户发出信号,表示传递的对象不会更改,而且本地副本是不可更改的

通过const引用传递它表明,传递的对象既不会更改,也不存在可更改的本地副本


因此,您应该考虑您真正想要什么。

传递(非常量)值似乎是最干净的方法,我看不到任何负面影响(如果您决定函数根本不需要副本,则重新编译除外)。传递值,并对堆栈副本进行更改,这些值在函数外部不可见。
若要向调用方发出信号,表示我不会修改外部值,我希望包含一个常量限定符。在按值调用时,这当然是隐式的,但我想说得更详细一些,这很愚蠢,因为您在下一行中会发现。无法修改对对象的常量引用第一种情况实际上是
void myFunction(NonSimpleObject foo)
,哪一个是最好的选择。通过const引用获取它,然后在函数内部进行显式复制将禁止利用移动语义。因此,我会继续使用简单的传递值。@juanchopanza-doh不知何故,我错过了那个值。无论如何,他正在创建另一个对象,如
NonSimpleObject foo_internal=~foo