Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why use a const non-reference when const reference lifetime is the length of the current scope

Tags:

c++

So in c++ if you assign the return value of a function to a const reference then the lifetime of that return value will be the scope of that reference. E.g.

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

So it seems that wherever you would normally assign the return value from a function to a const object you could instead assign to a const reference. Is there ever a case in a function where you would want to not use a reference in the assignment and instead use a object? Why would you ever want to write the line:

const MyClass myClass = GetMyClass();

Edit: my question has confused a couple people so I have added a definition of the GetMyClass function

Edit 2: please don't try and answer the question if you haven't read this: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

like image 826
dan Avatar asked Aug 09 '13 09:08

dan


People also ask

Does const reference extend lifetime?

In the by-reference case, we get a const Base& reference that refers to a Derived object. The entire temporary object, of type Derived , is lifetime-extended.

What is the point of a const reference?

- const references allow you to specify that the data referred to won't be changed. A const reference is actually a reference to const. A reference is inherently const, so when we say const reference, it is not a reference that can not be changed, rather it's a reference to const.

Can a const reference be bound to a non-const object?

No. A reference is simply an alias for an existing object. const is enforced by the compiler; it simply checks that you don't attempt to modify the object through the reference r .

Can a const reference call a non-const function?

Once you have a const object, it cannot be assigned to a non-const reference or use functions that are known to be capable of changing the state of the object. This is necessary to enforce the const-ness of the object, but it means you need a way to state that a function should not make changes to an object.


1 Answers

If the function returns an object (rather than a reference), making a copy in the calling function is necessary [although optimisation steps may be taken that means that the object is written directly into the resulting storage where the copy would end up, according to the "as-if" principle].

In the sample code const MyClass myClass = GetMyClass(); this "copy" object is named myclass, rather than a temporary object that exists, but isn't named (or visible unless you look at the machine-code). In other words, whether you declare a variable for it, or not, there will be a MyClass object inside the function calling GetMyClass - it's just a matter of whether you make it visible or not.

Edit2: The const reference solution will appear similar (not identical, and this really just written to explain what I mean, you can't actually do this):

 MyClass __noname__ = GetMyClass();
 const MyClass &myclass = __noname__;

It's just that the compiler generates the __noname__ variable behind the scenes, without actually telling you about it.

By making a const MyClass myclass the object is made visible and it's clear what is going on (and that the GetMyClass is returning a COPY of an object, not a reference to some already existing object).

On the other hand, if GetMyClass does indeed return a reference, then it is certainly the correct thing to do.

IN some compilers, using a reference may even add an extra memory read when the object is being used, since the reference "is a pointer" [yes, I know, the standard doesn't say that, but please before complaining, do me a favour and show me a compiler that DOESN'T implement references as pointers with extra sugar to make them taste sweeter], so to use a reference, the compiler should read the reference value (the pointer to the object) and then read the value inside the object from that pointer. In the case of the non-reference, the object itself is "known" to the compiler as a direct object, not a reference, saving that extra read. Sure, most compilers will optimise such an extra reference away MOST of the time, but it can't always do that.

like image 73
Mats Petersson Avatar answered Sep 30 '22 18:09

Mats Petersson