C++ 按值、常量值、引用或常量引用传递非POD类型
我需要把一个非POD类型传递给C++函数。 我想修改该函数内部的值,但我不希望该更改在该函数外部可见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; } 我也可以通过引用传递,这在函数调用期间更
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代码>。