views:

172

answers:

5

Here is a fake code sample

vector<Fred> gFred;
{
    // init gFred

    Fred &fred = gFred[0];

    size_t z = 0;
    do
    {
        fred = gFred[z];

        // do odd processing with fred

        z++;
    }
    while (fred.lastElementInSet == 0);
}

The thing that caught my attention was the fact that gFred[0] was being overwritten. This leads me to think that rather than init fred as a reference to a new element,

fred = gFred[z];

What is actually happening is that gFred[1] is overwriting gFred[0].

I'm thinking the correct thing to do here, is whap myself upsida head a few times, and turn this into a pointer implementation and move on with my life.

Have I diagnosed this correctly? or do I need more education?

+6  A: 

Yes, you are getting a structure copy there. References cannot be rebound, i.e., they stay the same once they are initialized.

And your solution is also appropriate. Dunno about smacking yourself in the head though.

MSN
Now, if you move the declaration of ) it should work as you expect, making fred an alias for gFred[z];
Rob K
+3  A: 

One way of looking at references is to think of them as implicitly de-referenced pointers. Simply put, they are pointers, but you can use the normal variable access syntax to use them

Fred &fred = gFred[0];

This creates a reference to the first element of your vector gFred. (Incidentally, do you have anything inside this?) The compiler will do something like this:

Fred *pFred = &gFred[0];

Now, when you do:

fred = gFred[z];

the compiler will actually do something like this:

*pFred = gFred[z];

which translated stands as:

gFred[0] = gFred[z];

And you are doing this N times, if you have N elements to start off in your vector.

If you are trying to initialize all elements of your vector try this constructor:

vector(size_type n, const T& t)

where,

n = size of vector
t = gFred[0]
dirkgently
A: 

In the code you give, fred is always referencing gFred[0]. If you want the fred reference to change with each iteration of the loop, remove the line Fred &fred=gFred[0]; . Then replace fred = gFred[z]; with Fred &fred = gFred[z]. This way, you reinitialize the fred reference each time the loop executes.

Marcin
+1  A: 

With the code you posted (and assuming the Fred type is a POD), gFred[0] is being written over and will end up containing a copy of wahatever was in gFred[z] for the last z.

You could switch to using a pointer implementation, or you could scope the reference more closely:

{    
    size_t z = 0;
    do
    {
        Fred &fred = gFred[z];
        // do odd processing with fred
        z++;
    }
    while (fred.lastElementInSet == 0);
}
Michael Burr
Yep. that is a viable option. +1I don't like it as well, since evil msvc 6 closes fred in the watch window, ever time it is instantiated.
EvilTeach
A: 

the compiled mechanism is explained by dirkgently's answer, while the underlying explanation is MSN's one ("References cannot be rebound").

maybe it's easier to read this way:

if

ptr = &xxx;

means that the content of ptr is the address of xxx, then

&fred = gFred[0];

means that the address of fred is set to point to gFred[0]. IOW, fred is now an alias to gFred[0]. that's why doing fred = xxx overwrites gFred[0]

Javier