按值调用vs const调用引用

时间:2013-03-11 22:37:50

标签: c++ reference const

我对按值调用和按引用调用const之间的差异感到有点困惑。有人可以向我解释一下。例如,它们是否都可以防止更改调用者参数,它们是否适用于所有对象大小,是在一个不复制时复制参数,还是在复制时使用更多内存?

5 个答案:

答案 0 :(得分:6)

  

他们都防止改变调用者参数

按值传递会创建调用者提供的参数的副本,因此无论函数做什么,它都会在单独的对象上执行。这意味着永远不会触及原始对象,因此在这种情况下答案是“”。

另一方面,

通过引用传递给const,让函数引用调用者提供的同一个对象,但它不会让该函数修改它... 除非(正如Luchian Grigore在评论中正确评论的那样)函数的实现者使用const_cast<>来抛弃引用中的const - 这是只有知道它才能安全地完成的事情绑定到引用的对象 not 声明为const类型(否则,您将获得未定义的行为)。

由于这似乎不是考虑您的问题的最可能的情况,并且考虑到通常接受对const的引用表示承诺该参数将不会被触及,那么答案是,只要我们假设这个承诺得到满足,通过引用传递const将不会改变调用者提供的参数。所以答案再次是“” - 我在上面提到的警告

  

它们对所有对象大小都很快

不。虽然您应该首先定义“快速”。如果传递的对象类型复制(或移动,如果执行移动而不是复制),则传递的对象类型可能很慢。无论您传递的值的类型是什么,通过引用传递总是会花费相同的(地址的大小)。

请注意,在某些体系结构和某些数据类型(如char)上传递值可能比通过引用传递更快,而对于足够大的UDT则相反。

  

在制作副本时会占用更多内存吗?

由于其中只有一个人正在制作副本,因此问题有一个明显的答案。

答案 1 :(得分:0)

主要区别在于传递const引用(或非const)不会复制参数。 (副本实际上受复制省略限制,但理论上它是传递给值时传递给函数的副本)

在某些情况下,传递值同样快,甚至更快(通常当对象最多是寄存器的大小时)。您通常按值传递基本类型,通过引用传递类类型。

当通过const引用时,您仍然可以通过强制转换const来修改原始值(通过const_cast),但如果原始值为const,则会导致未定义的行为

答案 2 :(得分:0)

按值调用将复制它确实保护调用者参数的对象的所有元素,因为如果要更改某些内容,它只是您正在更改的副本。
通过const引用调用不会复制元素,但由于“const”它将保护调用者的参数。

你const引用。

答案 3 :(得分:0)

我想你的意思是:

之间的区别
void Fn1(MyType x);

void Fn2(const MyType& x);

在前一种情况下,始终会创建对象的副本,这会使其变慢,特别是如果类型具有非平凡的构造函数。原始对象不受函数中对副本所做的任何更改的影响,但可以更改副本本身。

后一个示例不会创建副本,通常会更快。在函数内部,只能在参数上调用const函数(除非你采用像去掉constness这样的脏技巧),从而保证不会修改对象。

重要提示:本讨论不涉及具有特殊语义的类型,如智能指针。在这种情况下,按值调用仍然允许您更改逻辑上相同的对象,即不是智能ptr实例本身,而是它指向的对象。

以下是您问题的答案:

  • 他们都防止更改调用者参数:是的,原始对象将保持不变(不包括技巧)
  • 它们对于所有对象大小都是快速的:它们不是同样快 - 通过引用调用通常更快,除了一些原始类型,其中速度或多或少相同或者甚至稍微更快,这取决于编译器优化。 / LI>
  • 复制参数,而不是一个:按值调用创建副本,按引用调用不
  • 在制作副本时使用更多内存?按引用调用不会创建副本,所以答案很明确

答案 4 :(得分:0)

值得一提的另一点是,按引用调用函数将转换为内联函数。