Reputation: 5953
I've got a vector of std::string
that represents the structure of another vector of object pointers. I would like to generate this vector of object pointers, where if there are two of the same objects, the pointer in the vector is also the same.
Don't know what I meant just there? let me give you an example. Let's say I have a std::vector
of std::string
:
std::vector<std::string> names;
names.push_back(std::string("A"));
names.push_back(std::string("A"));
names.push_back(std::string("B"));
names.push_back(std::string("C"));
names.push_back(std::string("A"));
Now let's say these names (A
, B
and C
) represent three different instances of an Object
:
Object* ptr_A = new Object(1); // A
Object* ptr_B = new Object(2); // B
Object* ptr_C = new Object(3); // C
I would now like to generate the vector that holds pointers to the Object
, in the same order as in the vector names
:
std::vector<Object*> objects;
objects.push_back(ptr_A);
objects.push_back(ptr_A);
objects.push_back(ptr_B);
objects.push_back(ptr_C);
objects.push_back(ptr_A);
so that when two names are the same, the pointers are the same also.
How would I efficiently do this? Note that I would like the objects to be dynamically allocated inside the function that does this, so that the vector can be used later on.
I will be using this to read the objects from a file based on a name, but I want to prevent making multiple objects that are basically the same.
Since this is homework I cannot use C++11 yet.
Upvotes: 0
Views: 212
Reputation: 66971
This generates a lookup
object that maps the names to allocated objects, and then fills the vector objects
with the values based off the values in names
. Simple.
typedef std::map<std::string, Object*>::iterator iterator;
typedef std::pair<std::string, Object*> value_type;
std::map<std::string, Object*> lookup; //or maybe unordered_map
lookup.insert(value_type("A", ptr_A));
lookup.insert(value_type("B", ptr_B));
lookup.insert(value_type("C", ptr_C));
for(int i=0; i<names.size(); ++i) {
iterator iter = lookup.find(names[i]);
if (iter == lookup.end())
throw std::runtime_error("invalid name in file");
objects.push_back(iter->second);
}
If you want to generate the names and objects from the file, you can do something like this to create the names, objects, and the mapping between them all at once. I assume that you will have to do other stuff as well, I don't know your file format.
std::string newname;
std::map<std::string, Object*> lookup; //or maybe unordered_map
while(myfile >> newname)
lookup[newname] = new Object(newname);
Upvotes: 4
Reputation: 10966
Instead of using a std::vector
, use a std::map
containing keys of std::string
and values of Object*
std::map<std::string, Object*>
No two identical keys may be inserted into the map. If an insert is attempted that matches a previous key the original key-value is returned. When a key is requested, the same pointer is returned.
Upvotes: 1