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?
-
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.
Rob K : Now, if you move the declaration of &fred inside the do loop ( Fred &fred = gFred[z]; ) it should work as you expect, making fred an alias for gFred[z]; -
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
Ntimes, if you have N elements to start off in yourvector.If you are trying to initialize all elements of your
vectortry this constructor:vector(size_type n, const T& t)where,
n = size of vector t = gFred[0] -
In the code you give,
fredis always referencinggFred[0]. If you want thefredreference to change with each iteration of the loop, remove the lineFred &fred=gFred[0];. Then replacefred = gFred[z];withFred &fred = gFred[z]. This way, you reinitialize thefredreference each time the loop executes. -
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); }EvilTeach : Yep. that is a viable option. +1 I don't like it as well, since evil msvc 6 closes fred in the watch window, ever time it is instantiated. -
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
ptris the address ofxxx, then&fred = gFred[0];means that the address of
fredis set to point togFred[0]. IOW,fredis now an alias togFred[0]. that's why doingfred = xxxoverwritesgFred[0]
0 comments:
Post a Comment