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

时间:2010-06-09 20:12:51

标签: c++

这可能是一个愚蠢的问题,但我注意到在许多API中,许多采用不打算修改的整数参数的方法签名如下所示:

void method(int x);

而不是:

void method(const int &x);

对我来说,看起来这两个功能完全相同。 (编辑:显然不是在某些情况下,请参阅R Samuel Klatchko的回答)在前者中,价值被复制,因而无法改变原作。在后者中,传递了一个常量引用,因此原始内容无法更改。

我想知道的是为什么一个在另一个之上 - 是因为前者的表现基本相同甚至更好?例如传递16位值或32位值而不是32位或64位地址?这是我能想到的唯一合乎逻辑的原因,我只是想知道这是否正确,如果没有,为什么以及何时应该更喜欢int x而不是const int &x,反之亦然。

5 个答案:

答案 0 :(得分:53)

这不仅仅是传递指针的成本(基本上是引用的成本),而且还是在被调用方法的主体中取消引用以检索基础值。

这就是为什么传递int的值几乎可以保证更快(同样,编译器可以优化并简单地通过处理器寄存器传递int,从而无需将其推入堆栈)。

答案 1 :(得分:36)

对我来说,看起来两者的功能完全相同。

这取决于参考的确切内容。这是一个公认的组成示例,它将根据您是传递引用还是值来更改:

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 &)

答案 2 :(得分:2)

整数通常是处理器本机字的大小,可以轻松传递到寄存器中。从这个角度来看,传递值或传递常量引用没有区别。

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

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

答案 3 :(得分:1)

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

  • 您不能将int文字作为const int&

  • 传递
  • 显式类型转换允许你转换const int& into *(const int *)打开更改传递引用值的可能性

答案 4 :(得分:0)

通过引用传递可能会有一个非常非常小的去优化,因为至少需要一个去引用才能获得实际值(除非调用内联,编译器不能简单地传递值由于调用站点和函数可能是单独编译的,并且它是有效且定义良好的,以抛弃const传递的参数本身并非const本身 - 请参阅{{ 3}})。但请注意,“去优化”可能很小,难以衡量。

大多数人似乎不喜欢内置插件的const-by-const因为这个(非常多)。但是,我认为在某些情况下,如果您希望编译器帮助您确保在函数中不会意外更改该值,则可能更为可取。这不是一件大事,但有时它可能会有所帮助。