If I wanted a class that had a vector of pointers to other classes of the same type that could allow a cyclical cycle, how dangerous is it? For example, say I have a text file that looks like this:
city=Detroit
{
sister=Toyota
sister=Dubai
...
}
...
First the file is read into a series of temp classes, ParsedCity, where the name of the city and the names to the sister cities are held. After I have all the cities in the file I create the actual City class.
class City
{
private:
std::string name;
std::vector<City*> sisterCities;
public:
City(const std::string& aName);
CreateRelations(const ParsedCity& pcs);
std::string Name() const { return name; }
};
//If this were to represent Detroit, pc would contain a vector of strings
//containing Toyota and Dubai. Cities contain the actual classes that sister
//cities should point to. It holds all cities of the world.
City::CreateRelations(const ParsedCity& pc, std::vector<City>& cities)
{
for (unsigned int i = 0; i < pc.ParsedSisterCities().size(); i++)
{
for (unsigned int j = 0; j < cities.size(); j++)
{
if (pc.ParsedSisterCities()[i] == cities[j].Name())
{
sisterCities.push_back(&cities[j]);
break;
}
}
}
}
My worry is that if more cities are pushed into the main City vector, that the vector will re-size, relocate to somewhere else, and all my Cities will be pointing to sisterCities that are dangling pointers. At least this is my thought that will happen based on my knowledge of the vector class. If all the cities in the world and sister cities were stored in a linked-list would this solve my problems? I would like a guarantee that once a city is built it does not move (in memory. Bad pun?)
This seems like a tricky problem to me. As if I call a sister city of Detroit, I can call it’s sister cities, etc. Then I could end up back at Detroit! If Topeka changes its name to Google, all of Topeka’s sister cities should automatically know (as they are all pointing at the same spot in memory that Topeka is located).
Any advice is appreciated!
If you have a vector of pointers, and the vector resizes, the pointees locations in memory are not affected, so all your pointers remain valid.
The biggest problem with this solution is that any recursive algorithm you apply to your data-structure will have to have some mechanism to detect cycles, otherwise you will end up with stack-overflows due to infinite recursion.
Edit:
I just realized that I misread your question originally. If the
cities-vector resizes, any pointer to its elements will become invalid. The best alternative would be store pointers to cities in that vector. To make this more manageable, I suggest you use aboost::ptr_vector. This has the benefit that pointers to cities remain valid even if you delete a city from your vector, or you reorder the cities in your vector (for instance if you want to sort them by name for faster lookup).