根据我的理解:当你通过值传递时,函数会生成传递参数的本地副本并使用它; 当函数结束时,它超出范围.当您通过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
应该选择通过引用传递参数,其中实际需要引用的语义,或者仅当潜在别名的成本被复制参数的费用超过时才作为性能改进.
在某些情况下,复制对象可能会极大地影响性能。考虑一个参数将是的函数,std::vector<long>
并且您希望传递具有 100 万个元素的向量。在这种情况下,您将需要使用 const 引用而不是按值传递。在this SO question中,您可以为您的问题找到简单的一般规则。