I have a the following code.
vector* irds = myotherobj->getIRDs();//gets a pointer to the vector
for(vector::iterator it = ir
When I iterate over the vector pointer irds, what exactly am I iterating over? Is it a copy of each element, or am I working with the actual object in the vector when I say (*it).doSomething(),
When you iterate over a vector you work with the object itself, not a copy of it.
Dereference the iterator to get a reference to the underlying object.
vector<IRD>* irds = myotherobj->getIRDs();
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
{
IRD& ird = *it;
ird.doSomething();
// alternatively, it->doSomething();
}
You can get a pointer from an iterator by doing &*it
. You get a pointer to the actual IRD
object stored inside the vector. You can modify the object through the pointer and the modification will "stick": it will persist inside the vector.
However, since your vector contains the actual objects (not pointers to objects) I don't see any point in dynamic_cast
. The type of the pointer is IRD *
and it points to IRD
object.
The only case when the dereferenced iterator might refer to a copy (or, more precisely, to a proxy object) is vector<bool>
, which might be implemented as a bit-vector.
First consider whether you actually need a pointer to the element or if you're just trying to kind of use iterators but kind of avoid them. It looks like you're trying to code C in C++, rather than coding C++. In the example you gave, it seems like rather than converting to a pointer and then working with that pointer, why not just use the iterator directly? it->doSomething()
instead of ird->doSomething()
.
If you're thinking that you need to save that pointer for later to use on the vector after doing some work, that's potentially dangerous. Vector iterators and pointers to elements in a vector can both be invalidated, meaning they no longer point to the vector, so you are basically attempting to use memory after you've freed it, a dangerous thing to do. A common example of things that can invalidate an iterator is adding a new element. I got into the mess of trying to store an iterator and I did a lot of work to try to make it work, including writing a "re_validate_iterator()" function. Ultimately, my solution proved to be very confusing and didn't even work in all cases, in addition to not being scalable.
The solution to trying to store the position of the vector is to store it as an offset. Some integer indicating the position within the vector that your element is at. You can then access it with either myvector.begin() + index
if you need to work with iterators, or myvector.at (index)
if you want a reference to the element itself with bounds checking, or just myvector [index]
if you don't need bounds checking.
You need to use !=
with iterators to test for the end, not <
like you would with pointers. operator<
happens to work with vector
iterators, but if you switch containers (to one like list
) your code will no longer compile, so it's generally good to use !=
.
Also, an iterator is not the type that it points to, so don't try to cast it. You can use the overloaded operator->
on iterators.
vector<IRD>* irds = myotherobj->getIRDs();//gets a pointer to the vector<IRD>
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
{
it->dosomething();
}
Why do you want to get a pointer?
Use a reference:
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
{
IRD & ird = *it;
ird.doSomething();
}
Alternatively:
for(vector<IRD>::iterator it = irds->begin(); it != irds->end(); ++it)
{
it->doSomething();
}
Also, as everyone said, use !=
when comparing iterators, not <
. While it'll work in this case, it'll stop working if you use a different container (and that's what iterators are for: abstracting the underlying container).