为什么传递const引用而不是值?

Mau*_*rus 45 c++ function

根据我的理解:当你通过值传递时,函数会生成传递参数的本地副本并使用它; 当函数结束时,它超出范围.当您通过const引用时,该函数使用对无法修改的传递参数的引用.但是,我不明白为什么会选择一个而不是另一个,除非需要修改和返回参数.如果你有一个无效函数没有返回任何东西,为什么选择一个而不是另一个?

编辑:所以基本上通过const引用传递避免复制对象.那么在什么情况下复制对象好呢?我的意思是,如果它始终优化性能,为什么不一直使用const引用呢?

CB *_*ley 51

有两个主要考虑因素.一个是复制传递对象的费用,第二个是当对象是本地对象时编译器可以做出的假设.

例如,在第一种形式中,在f它的主体中不能假设a并且b不引用相同的对象; 所以在a写入之后必须重新读取值b,以防万一.在第二种形式中,a不能通过写入来更改b,因为它是函数的本地,因此这些重新读取是不必要的.

void f(const Obj& a, Obj& b)
{
    // a and b could reference the same object
}

void f(Obj a, Obj& b)
{
    // a is local, b cannot be a reference to a
}
Run Code Online (Sandbox Code Playgroud)

例如:在第一个示例中,编译器可能能够假设在进行不相关的调用时本地对象的值不会改变.如果没有相关信息h,编译器可能无法知道该函数是否具有引用的对象(通过引用参数)是否未被更改h.例如,该对象可能是由其修改的全局状态的一部分h.

void g(const Obj& a)
{
    // ...
    h(); // the value of a might change
    // ...
}

void g(Obj a)
{
    // ...
    h(); // the value of a is unlikely to change
    // ...
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个例子不是铸铁.可以编写一个类,例如,在其构造函数中向自身添加指向全局状态对象的指针,这样即使是类型的本地对象也可能被全局函数调用更改.尽管如此,仍然可能有更多机会对本地对象进行有效优化,因为它们不能通过传入的引用或其他预先存在的对象直接别名.

const应该选择通过引用传递参数,其中实际需要引用的语义,或者仅当潜在别名的成本被复制参数的费用超过时才作为性能改进.

  • 如果引用的数据可能会改变,那么`const Obj&a`有什么意义呢?为什么甚至首先使用`const`? (4认同)
  • @KennyWorden:这不是意味着您的线程不会更改它,但其他线程可以吗? (3认同)

Geo*_*che 22

按值传递参数并因此复制它们可能很昂贵 - const引用避免了这个昂贵的步骤,同时仍然向调用者承诺不会更改对象.

通常基本类型(int,, double...)通过值传递,而类类型通过const引用传递.

但是,可以存在例外情况,即类类型的传值可能是有益的.


Kir*_*sky 5

在某些情况下,复制对象可能会极大地影响性能。考虑一个参数将是的函数,std::vector<long>并且您希望传递具有 100 万个元素的向量。在这种情况下,您将需要使用 const 引用而不是按值传递。在this SO question中,您可以为您的问题找到简单的一般规则。