views:

110

answers:

3

Hello,

So I'm looking through some code, and I see this:

class whatever 
{
public:
    void SomeFunc(SomeClass& outVal)
    {
        outVal = m_q.front();
        m_q.pop();
    }

private:
    std::queue<SomeClass> m_q;
};

This doesn't seem like outVal would be a valid reference any more... However, it appears to work.

I've seen this in other code before too, is this valid? Thanks

+2  A: 

What I wrote in my previous reply was complete nonsense. (Whoever upvoted my original response, please take it back :)

In this example the reference is not bound to a dying object, but rather the value of the object in the front is copied to another object (referred to by the reference). The copy continues to exist independently of the queue an the fact that the front of the queue is destroyed has no adverse effects on the copy.

Please, refer to Crashworks reply for a great explanation of what is happening here.

AndreyT
didn't upvote you, but -1 because you asked for it and +1 for admitting and correcting your own fault. let's say we are even :)
Oren S
+7  A: 

Remember that references are not like pointers: they cannot be rebound after their creation. That means that if I do

int a;
int b;
int &c = a;

Then throughout that scope, an assignment to c will actually mean an assignment to a. So,

int a = 2;
{
   int b = 3;
   int &c = a;
   c = b;
   b = -5;
}
printf("%d",a); // prints "3".

So, in this case, the reference is not being pointed at a deleted object. Rather, the return value of m_q.front() is copied into whatever outVal references, via the assignment operator.

Crashworks
Exactly, there is a copy there. Even if it looks like outval would be out of scope, remember it's not local to the function, is just an alias to an outside variable.
machielo
Yeah even after a few years of C++ references still confuse me sometimes :). Pointers just seem so much more intuitive!
Polaris878
Yeah, I never really saw any value to using C++ references instead of pointers.
Crashworks
@Crashworks: it's more a matter of 'contract', you don't check that a reference points to null, you just assumes it points to a valid object!
Matthieu M.
+2  A: 

It's valid. You are not reseating the outVal reference to refer to m_q.front(), that is not something supported by references, instead you are assigning m_q.front() to the variable (actually lvalue) that outVal refers to.

  SomeClass c;
  someWhatever.SomeFunc(c);

Can be thought of as behaving like:

  SomeClass c;
  c = someWhatever.m_q.front();
  someWhater.m_q.pop();
Logan Capaldo