我有一个返回类型对象的函数Foo:
Foo getFoo();
Run Code Online (Sandbox Code Playgroud)
我知道以下内容将编译并可以工作,但为什么我会这样做?
const Foo& myFoo = getFoo();
Run Code Online (Sandbox Code Playgroud)
对我来说,以下内容更具可读性,并且不会强迫我记住C++允许我为const引用分配r值:
const Foo myFoo = getFoo();
Run Code Online (Sandbox Code Playgroud)
两者有什么不同?为什么我会在第二次使用第一个?为什么我会使用第二个?
与流行的观点相反,不能保证将按值返回对象的函数的结果分配给 const 引用会比将其分配给对象本身产生更少的副本。
当您将右值分配给 const 引用时,编译器可能会通过两种方式之一绑定该引用。它可以通过复制右值并将引用绑定到该临时值来创建新的临时值,也可以将引用直接绑定到右值本身。
如果编译器无法进行“明显”的优化来删除临时值并删除 的返回值的复制构造函数getFoo,那么它有多大可能能够执行将右值绑定到 const 引用的更有效形式不做一个新的临时?
使用 const 引用的原因之一是使函数对潜在的切片更加鲁棒。如果返回类型实际上是从 派生的类型Foo,则分配给基类 const 引用将保证不会切片,即使编译器确实从函数返回的右值创建了一个临时对象。编译器还将生成对派生类析构函数的正确调用,无论基类中的析构函数是否为虚拟。这是因为创建的临时对象的类型基于所分配的表达式的类型,而不是基于正在初始化的引用的类型。
请注意,创建多少份返回值副本的问题与返回值优化和命名返回值优化完全无关。这些优化是指消除将计算返回表达式的右值结果或命名局部变量复制到函数本身的函数返回值中。显然,在最好的情况下,可以进行返回值优化,并且可以消除返回值的临时值,从而导致不对返回的对象执行任何副本。
| 归档时间: |
|
| 查看次数: |
1272 次 |
| 最近记录: |