As I understand it, you're doing something like this:
cow florence, buttercup;
std::vector<cow> v = { florence, buttercup };
cow* buttercup_ptr = &v[1];
// do something involving the cow*
And your buttercup_ptr
is getting invalidated because, eg. florence
was removed from the vector.
It is possible to resolve this by using smart pointers, like this:
std::shared_ptr<cow> florence = std::make_shared<cow>();
std::vector<std::shared_ptr<cow>> v;
v.push_back(florence);
You can now freely share florence
... regardles off how the vector gets shuffled around, it remains valid.
If you want to let florence
be destroyed when you pop her out of the vector, that presents a minor problem: anyone holding a copy of the shared_ptr
will prevent this particular cow
instance being cleaned up. You can avoid that by using a weak_ptr
.
std::weak_ptr<cow> florence_ref = florence;
In order to use a weak_ptr
you call lock()
on it to convert it to a full shared_ptr
. If the underlying cow
instance was already destroyed because it had no strong references, an excetion is throw (you can also call expired()
to check this before lock()
, of course!)
The other possibility (as I suggested in my comment on the original question) is to use iterators pointing into the container holding the cow
instances. This is a little stranger, but iterators are quite like pointers in many ways. You just have to be careful in your choice of container, to ensure your iterators aren't going to be invalidate (which mean syou can't use a vector
for this purpose);
std::set<cow> s;
cow florence;
auto iter = s.insert(florence);
// do something with iter, and not worry if other cows are added to
// or removed from s
I don't think I'd necessarily advise this option, though I'm sure it would work. Using smart pointers is a better way to show future maintainance programmers your intent and has the advantage that getting dangling references is much harder.