传递整数作为常量引用与复制

这可能是一个愚蠢的问题,但我注意到,在大量的API中,很多方法签名采用整数参数,而不是被修改的:

void method(int x);

而不是:

void method(const int &x);

对我来说,看起来这两个function完全一样。 (编辑:显然不是在某些情况下,看到R塞缪尔Klatchko答案)在前者,价值被复制,因此不能改变原来的。 在后者中,通过了一个不变的引用,所以原文不能改变。

我想知道的是,为什么一个人会这么做,是因为他们的performance与前者基本相同甚至更好? 例如传递一个16位值或32位值而不是32位或64位地址? 这是我能想到的唯一合乎逻辑的原因,我只想知道这是否正确,如果不是这样,为什么以及何时您更喜欢int x不是const int &x和/或反之亦然。 谢谢。

这不仅仅是传递一个指针(本质上是一个引用)的代价,还包括被调用的方法体中的去引用来检索底层的值。

这就是为什么按值传递一个int将保证速度更快的原因(另外,编译器可以优化并简单地通过处理器寄存器传递int ,不需要将其推入堆栈)。

对我来说,看起来这两个function完全一样。

这取决于具体的参考。 这是一个公认的例子,将根据您是否传递引用或值来改变:

 static int global_value = 0; int doit(int x) { ++global_value; return x + 1; } int main() { return doit(global_value); } 

这个代码的行为将有所不同,具体取决于你是否有int doit(int)int doit(const int &)

整数通常是处理器本地字的大小,可以很容易地传递到寄存器中。 从这个angular度来看,通过价值传递和通过不断的参照是没有区别的。

如果有疑问,请打印您的函数的汇编语言列表,以了解编译器如何传递参数。 按值打印并通过常量引用传递。

另外,按值传递时,函数可以修改副本。 当通过常量引用传递时,函数不能修改variables(它被标记为const)。

  • 根据底层指令集,整数参数可以作为寄存器或堆栈传递。 寄存器肯定比内存访问更快,这在const refs的情况下总是需要的(考虑早期无caching体系结构)

  • 你不能传递一个整型文字作为一个const int&

  • 显式types转换允许您将const int&转换为*(const int *),以打开更改传入引用的值的可能性

通过引用传递可能会有一个非常非常小的去优化,因为至less需要一个解引用来获取实际值(除非调用被内联,否则编译器不能简单地传递值事实上,调用网站和函数可能被单独编译,并且它是有效的和明确的,以抛弃一个传递的参数,而实际上本身并不是const – 请参阅通过const ref传递整型的好处 )。 但是请注意,“去优化”可能太小而难以测量。

大多数人似乎因为这个(非常多)而不喜欢传入const-ref。 不过,我认为在某些情况下,如果您希望编译器帮助您确保函数中的值不会被意外更改,那么可能会更好。 这不是一件大事,但有时可能会有所帮助。