简体   繁体   中英

In a vector/list, are you actually applying it to the object? (C++)

Let's say I have a vector:

vector<Block> myBlocks;

And let's say I do this:

Block b(10); //Let's assume this will set b's variable: x to 10
myBlocks.push_back(b); //Add it to the vector/list

Now, what if somewhere else I did this:

for(int i = 0; i<myBlocks.size(); i++){
    Block c = myBlocks.at(i);
    c.x = 15; //Will this work?
}

Where I put: cx = 15; , is that actually setting that block's x position to 15? Or is it only setting the temporary block's x position to 15? If it's only setting the temporary block, how do I set it for the actual block?

Block c = myBlocks.at(i);

Here c is a copy of the value contained in myBlocks .

Block& c = myBlocks.at(i);

Here c is a reference to (ie, an alias of) the value contained in myBlocks .

I suspect you want the latter.

Where I put: "cx = 15", is that actually setting that block's x position to 15?

No.

Or is it only setting the temporary block's x position to 15?

Yes.

If it's only setting the temporary block, how do I set it for the actual block?

myBlocks.at(i).x = 15 ; // Assuming x has a public access.

Block c = myBlocks.at(i);

myBlocks.at(i) returns the object which is copied to c . So, the objects (object in the vector, c) are two different objects with their own members ( assuming the class has no raw pointers ).

This will work:

  Block& c = myBlocks.at(i); // note reference here
  c.x = 15; //Will this work?

Yours will work too but will do nothing at the end.

What you're working with the copy of the original element.

I would suggest you to prefer using idiomatic iterator as:

for(std:vector<Block>::iterator it=myBlocks.begin(); it!=myBlocks.end(); it++)
{
    it->x = 15 ;// this will work - will update the actual element, not its copy!
    (*it).x = 15 ;// this will also work
}

C++ is a language based on copy semantic so when you do something like

Block c = myblocks.at(i);

you are indeed making a copy of the block object. Note that this, in C++ lingo isn't called a "temporary"... temporaries in C++ is a very specific term meaning unnamed objects created automatically and not declared.

This copy behavior is quite different from many other languages like Python or Java where instead the approach is of reference semantic .

You can ask to not make a copy explicitly however by using a "reference"...

Block& c = myblocks.at(i);

and in this case when you modify c you are working with the original element inside the vector. Note that in this case you must pay attention to how long you keep your reference around because if for example you add an element to the vector all existing references and iterators are potentially invalidated because of vector reallocation and using them is going to summon the dreaded Undefined Behavior daemon.

If a reference or an iterator is invalidated or not depends on the type of container, on the type of operation you make on the container and onther facts like space reservation so my suggestion is to read a good C++ book to understand those parts.

Note also that both std::vector::operator [] and std::vector::at actually return a reference so your code could also change the original object in the vector using the more succint and idiomatic syntax

myblocks.at(i).x = 15;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM