为什么不总是在C ++中通过const引用?

时间:2013-11-14 01:43:37

标签: c++ function reference const

当你想要改变原始变量的值时,我知道你通过引用传递给C ++中的函数。但是当你希望程序更有效时你也可以通过引用传递,如果你不想改变传递给函数的变量中的任何东西,你只需要使它成为const。我的问题是,为什么不总是让你的函数接受const引用传递的变量,如果它比传递变量更高效并让编译器在函数范围内创建一个新变量?为了扩展这个问题,一个函数WOULD需要复制一个变量而不是通过参数?

3 个答案:

答案 0 :(得分:6)

当一个参数按值传递时,它是可修改的,复制它可能会被省略。例如,实现赋值运算符的规范方法如下所示:

T& T::operator= (T value) {
    value.swap(*this);
    return *this;
}
乍一看,它可能看起来效率低下,因为正在复制T。但是,无论如何它都会被复制,即,如果需要复制,则会以这两种方式创建:

T& T::operator= (T const& value) {
    T(value).swap(*this); // has to do a copy right here
    return *this;
}

但是,对于第一个版本,可能根本不创建副本,例如

T f() { return T(); }
// ...
T x = ...;
x = f();

f()类型T的结果分配给x时,编译器可能会认为它不需要复制f()的结果而是直接将它传递给赋值运算符。在这种情况下,如果赋值运算符通过const&获取参数,则编译器具有以在赋值运算符内创建副本。在按值实现参数的实现中,它可以忽略副本!实际上,f()的返回可能已经删除了副本,即对f()的调用,以下任务可能只涉及对象的默认构造! ......对于许多现代编译器而言确实如此!

换句话说:如果您需要复制参数,通过值传递它可以避免创建副本的需要。此外,您可以从值参数std::move()而不是const&个参数。

答案 1 :(得分:2)

  

但是,当你想要程序时,你也可以通过引用传递   更高效,如果你不想改变任何东西   变量传递给函数,你只需要使它成为const。

这是错的。传递基本类型(int,float,char ....)的参数比通过引用传递它们更有效。 const&通过BIG OBJECT更有效。因为引用是必要对象的别名,所以编译器需要处理更多信息。

答案 2 :(得分:1)

参考文献基本上是一个特殊的合约,其中的回报是一些语法糖和简单性。在函数体中,编译器可以自由地消除引用,但是当它们作为参数传递时,实际传递的是指针。

结果是使用引用可能会产生差异成本。

void func(int& i) {
    int j = i; // secretly a dereference
    // ...
}

会产生与

相同的开销
void func(int* i) {
    int j = *i;
    // ...
}

本地便利引用通常可以优化,但引用参数必须至少在第一次使用时才被取消引用。