Hi everyone,

I’m Pete, moderately-experienced C++ user who is always looking for better ways to do things.

Let me ask you guys about a problem I’ve scratching my head over lately. Suppose I’m writing a program designed to simulate a large company. I’m interested in tracking each company employee by the location where they work. This company has perhaps a thousand different locations:

``````class Employee {
public:
AccessorFunction1();   // does something
AccessorFunction2();   // does something different
AccessorFunction3();   // does something completely different
protected:
// Some data
};

class Company {
public:
void OrganizeLocation(int a);

protected:
vector<Employee*> LocationA;
vector<Employee*> LocationB;
vector<Employee*> LocationC;
...etc...
vector<Employee*> LocationZZZ;
};``````

Once employees are created and pointers to them are saved in the proper Location vector, I write an accessor function, OrganizeLocation(), designed to do a number of operations on a given vector. The problem is, I have maybe a thousand vectors. How do I call this function and specify which vector I want?

Currently, I’m using this clunky solution:

``````void Company::OrganizeLocation(int a){
switch(a) {
case 1: {
for(unsigned int i=0; i<LocationA.size(); i++) {
LocationA[i]->AccessorFunction1();
LocationA[i]->AccessorFunction2();
LocationA[i]->AccessorFunction3();
}
break;
}
case 2: {
for(unsigned int i=0; i<LocationB.size(); i++) {
LocationB[i]->AccessorFunction1();
LocationB[i]->AccessorFunction2();
LocationB[i]->AccessorFunction3();
}
break;
}
case 3: {
// etc...
}
case 4: {
// etc...
}

...etc...

case 1000: {
// etc...
}
}
}``````

The key point here is that whichever vector I choose to operate upon, I’ll do the exact same procedure every time. I hate this solution because it results in very long and repetitive code… not to mention its very error-prone when you re-editing all those “LocationA”s into “LocationB/C/D/etc.”

What would be an ideal solution would be if I could do some kind of string substitution into the vector name like (I think) you can do in PERL scripts:

``````void Company::OrganizeLocation( string \$WhichOne\$ ){
for(unsigned int i=0; i<LocationA.size(); i++) {
Location\$WhichOne\$[i]->AccessorFunction1();
Location\$WhichOne\$[i]->AccessorFunction2();
Location\$WhichOne\$[i]->AccessorFunction3();
}``````

Does anyone know of a way to do this? Or, if it can’t be done in C++, is there a better design approach? Ultimately I need the Company object to hold multiple vectors but use one compact accessor function to perform operations on just one of them.

Many thanks!
-Pete

3
Contributors
3
Replies
4
Views
6 Years
Discussion Span
Last Post by phummon

Don't declare lots of individual vectors in Company declare a container of vectors, for example

a vector of vectors:
vector<vector<Employee*> > Location; // Each location has a position

a map of vectors:
map<int, vector<Employee*> > Location; // Each location has an id number

alternative map of vectors:
map<string, vector<Employee*> > Location; // Each location has an name

Then just iterator through or find in the container (map or vector) and call the Employee vector.

``````void Company::OrganizeLocation(const string& location){
map<string, vector<Employee*> >::value_type office;

office = Location.find(location);

for(unsigned int i=0; i<office.second.size(); i++) {
office.second[i]->AccessorFunction1();
office.second[i]->AccessorFunction2();
office.second[i]->AccessorFunction3();
}
}``````

Or something like that.

Edited by Banfa: n/a

Another option would be to create a location class which has an identifier, and maybe other useful information, as well as a vector of employees as member variables. Then use a container of locations, search the location by some identifier and use just a single accessor function.

Good ideas, thanks for taking a look!