当const引用生命周期是当前范围的长度时,为什么使用const非引用

dan*_*dan 6 c++

因此,在c ++中,如果将函数的返回值赋给const引用,则该返回值的生存期将是该引用的范围.例如

MyClass GetMyClass()
{
    return MyClass("some constructor");
}

void OtherFunction()
{
    const MyClass& myClass = GetMyClass(); // lifetime of return value is until the end            
                                           // of scope due to magic const reference
    doStuff(myClass);
    doMoreStuff(myClass);
}//myClass is destructed
Run Code Online (Sandbox Code Playgroud)

因此,无论您通常将函数的返回值分配给const对象,您都可以将其分配给const引用.在函数中是否有一种情况,您不希望在赋值中使用引用而是使用对象?你为什么要写这行:

const MyClass myClass = GetMyClass();
Run Code Online (Sandbox Code Playgroud)

编辑:我的问题困扰了几个人,所以我添加了GetMyClass函数的定义

编辑2:如果你没有读过这个问题,请不要尝试回答这个问题:http: //herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-常量/

Mat*_*son 4

如果函数返回一个对象(而不是引用),则需要在调用函数中进行复制[尽管可能会采取优化步骤,这意味着该对象将直接写入复制最终所在的结果存储中,根据“仿佛”原则]。

在示例代码中const MyClass myClass = GetMyClass();,此“复制”对象被命名为myclass,而不是存在但未命名(或可见,除非您查看机器代码)的临时对象。换句话说,无论你是否为它声明一个变量,MyClass调用的函数内部都会有一个对象GetMyClass——这只是你是否让它可见的问题。

Edit2:const参考解决方案将看起来相似(不相同,这实际上只是为了解释我的意思,你实际上不能这样做):

 MyClass __noname__ = GetMyClass();
 const MyClass &myclass = __noname__;
Run Code Online (Sandbox Code Playgroud)

只是编译器__noname__在幕后生成变量,而没有实际告诉您它。

通过使 aconst MyClass myclass对象变得可见,并且很清楚发生了什么(并且GetMyClass返回对象的副本,而不是对某些已存在对象的引用)。

另一方面,如果GetMyClass确实返回引用,那么这肯定是正确的做法。

在某些编译器中,使用引用甚至可能会在使用对象时添加额外的内存读取,因为引用“是一个指针”[是的,我知道,标准没有这么说,但请在抱怨之前,做我帮个忙,告诉我一个编译器,它不会将引用实现为带有额外糖分的指针,以使它们尝起来更甜],因此要使用引用,编译器应该读取引用值(指向对象的指针),然后读取该值从该指针到对象内部。在非引用的情况下,对象本身被编译器“称为”直接对象,而不是引用,从而节省了额外的读取。当然,大多数编译器在大多数情况下都会优化这样的额外引用,但它并不总是能做到这一点。