But this obviously does not work, since the chair1 pointer will be invalidated when the "object" vector in WORLD has to resize to make room for chair2.
Is there anything I could place in the AI::reality class that would allow me to maintain pointers to the object instances in the vector WITHOUT using indices (I'd rather be able to access objects directly, not through WORLD.object[index].)?
Reserving a huge block and counting on the vector not resizing is not an option.
There's no way with the vector declared like that. You'd need to declare the vector as an std::vector<T *>, and allocate the objects dynamically. Then you can pass around pointers to the objects with the certainty that they'll remain valid even if the vector gets reallocated.
Ah thanks, good idea. I messed around with using pointers a bit and came up with this, which seems to work:
1 2 3 4 5 6 7 8 9 10 11 12 13
struct AI::reality{
vector<AI::object> object;
vector<AI::object **> objptr;
reality(int size=10){ object.reserve(size); }
~reality(){}
void AddObject(AI::object ** pointer, AI::object NewObject){
object.push_back(NewObject);
objptr.push_back(pointer);
for ( int i = 0; i < int(object.size()); ++i ){ (*objptr[i]) = &object[i];}
return; }
};
Now the double-pointer objptr vector stores a pointer to the pointer passed into AddObject so that it can modify the external pointer to correctly point to each element of the object vector after resizing.
However, I am sure that I have probably broken some rules in doing this because I am still rather new with memory, vectors, and even pointers. Are there any "bad practice" things in this class? I am creating memory leaks?
Thanks very much, that works as well. I have a few more questions, if you don't mind.
1) Why do you pass NewObject as a reference? Does it save you from a copy constructor call?
2) Why do you use this-> to get to the current reality's vars instead of saying object.push_back directly?
3) ~reality(){ for ( int i = 0; i < int(object.size()); ++i ) delete object[i]; }
Is this a correct destructor?
1.) Basically.
2.) It's more explicit, if you had a global variable called object (would be stupid to have but still), it would be hard to tell which one you would get
3.) Don't cast .size() to an int, use this a size_type for i instead (or unsigned int/size_t if you are lazy):
1 2 3
~reality(){
for ( std::vector<AI::object>::size_type i = 0; i < object.size(); ++i ) delete object[i];
}