我需要将非POD类型传递给C ++函数。 我想修改该函数内部的值,但我不希望该更改在该函数之外可见。
我的第一个选择是传递值,这会创建一个副本。
void myFunction (NonSimpleObject foo) {
foo = ~foo;
}
我也可以通过引用传递,这在函数调用期间更快,但我需要在里面创建一个不影响外部值的副本;
void myFunction (NonSimpleObject &foo) {
NonSimpleObject foo_internal = ~foo;
}
要向调用者发出信号,我不会修改外部值,我想包含一个const限定符。当按值调用时,这当然是隐含的,但我想更加冗长。但传递一个const值将迫使我在里面创建第二个副本来修改该值,这也与const限定符最初使用的内容有些相反。
void myFunction (const NonSimpleObject foo) {
NonSimpleObject foo_internal = ~foo;
}
传递一个const引用都会向调用者发出信号,表明外部值没有改变,只需要在函数内部有一个副本。
void myFunction (const NonSimpleObject &foo) {
NonSimpleObject foo_internal = ~foo;
}
哪一个最适合我的目的(性能良好,对来电者来说冗长)以及优点/缺点是什么?
这也归结为以下问题:在参数传递期间复制内部函数而不是复制是否有任何优势,反之亦然?
答案 0 :(得分:9)
如果您需要本地对象,则最好按值传递。如果参数是临时的或显式移动的,则这使得移动语义成为可能,从而可以避免不必要的复制。
通过引用传递强制复制是否需要。如果引用不是const
,那么参数不能是临时的。按值接受const
对象然后复制它只是很奇怪。
(请注意,在您的特定示例中,您不需要本地副本,只需将操作符应用于参数;因此const
引用可能更合适。)
答案 1 :(得分:5)
按价值传递:
const
更好地用于你传递给函数的实际对象(即带参考),并且你希望它不被修改(例如只是为了“窥视”它)。所以,这样:
void myFunction (NonSimpleObject foo) {
//modify foo here
}
答案 2 :(得分:1)
第一种情况(void myFunction (NonSimpleObject foo)
)将创建两个对象。第一个对象是foo
,第二个对象是foo_internal
。
第二种情况(void myFunction (const NonSimpleObject &foo)
)将只创建一个对象 - 即foo_internal
。
因此,第二种情况更好。
在参数传递过程中复制函数而不是复制是否有任何好处,反之亦然?
如果您要使用创建的对象,请复制它。您没有显示足够的代码来判断是否需要副本。就目前而言 - 我会说使用const引用。
答案 3 :(得分:0)
“我想修改该函数中的值,但我不希望该更改在该函数之外可见。”
然后,您的意思是更改对象的本地副本。 (我认为你不是指friend
- 函数,它允许你更改对象的私有数据。)
所以你需要传递by-value,而最干净的解决方案就是你的1.(而不是引用,然后在本地副本(你的2.解决方案)里面)。
这表示用户不会更改传递的对象(仅限本地副本,但这就是您想要的)。将它按值传递给const(您的3.解决方案)略有不同:您不仅告知用户,传递的对象不会被更改,而且本地副本不可更改
通过const引用传递信号,传递的对象既不会被更改也不会存在可更改的本地副本。
所以你应该考虑一下真正想要什么。