What's the best way to hide the particular STL container that my class uses?

E

Ed

Hi,

I have a WorkUnit class. I will pass a reference to a group of these
WorkUnits to other classes in my application. I have chosen to use a
vector to hold pointers to these WorkUnits for now.

However, I think that I should hide the fact that it's a vector in case
I want to switch to another container class at a later date. I don't
want every class that needs to use the group of WorkUnits to be too
tightly bound to the details of the vector.

Is there a best practice for hiding the container implementation in
this case?

Thanks.
 
V

Victor Bazarov

Ed said:
I have a WorkUnit class. I will pass a reference to a group of these
WorkUnits to other classes in my application. I have chosen to use a
vector to hold pointers to these WorkUnits for now.

However, I think that I should hide the fact that it's a vector in
case I want to switch to another container class at a later date. I
don't want every class that needs to use the group of WorkUnits to be
too tightly bound to the details of the vector.

Is there a best practice for hiding the container implementation in
this case?

Iterators, probably. However, you should be mostly thinking how the
collection is going to be used by the consumers of that "group", and
devise something out of the requirement set. In any case, you can
always tell the consumer to pass the empty collection in so you can
fill it or provide your own way to iterate over the collection (this
is what I'd prefer if I were the consumer).

V
 
P

Parapura Rajkumar

Try this..

typedef std::vector<WorkUnit> WorkUnitCollection_t;

Now use WorkUnitCollection_t everywhere to pass across function etc
declare locals etc

While iterating do

for ( WorkUnitCollection_t::iterator = myCollection.begin() ; etc
etc

This way if you want to change it to a set instead of vector you just
have to update the typedef and recompile

Raj
 
J

Jeff Flinn

Ed said:
Hi,

I have a WorkUnit class. I will pass a reference to a group of these
WorkUnits to other classes in my application. I have chosen to use a
vector to hold pointers to these WorkUnits for now.

However, I think that I should hide the fact that it's a vector in case
I want to switch to another container class at a later date. I don't
want every class that needs to use the group of WorkUnits to be too
tightly bound to the details of the vector.

Is there a best practice for hiding the container implementation in
this case?

I can't say it's best practice, but I use the Visitor Pattern to hide the
container implementation where needed. For example(untested):

class Item
{
...

void Fnc(){ }
};

class GroupOfItems
{
public:

...

struct ItemVisitor
{
virtual ~ItemVisitor(){}

virtual void operator()( Item& )const{}
};

void ForEachItem( const ItemVisitor& );
};

void GroupOfItems::ForEachItem( const ItemVisitor& aItemVisitor )
{
std::for_each( c.begin(), c.end(), aItemVisitor );
}

used like:

void someFnc( GroupOfItems& aItems )
{
struct MyItemVisitor : public ItemVisitor
{
void operator()( Item& aItem )const{ aItem.Fnc(); }
};

aItems.ForEachItem( MyItemVisitor() );
}

There are variations on this theme that avoid the virtual function calls.
You could use boost::function as the arg type, or make ForEachItem a
template member function. Each has their own (dis)advantages.

Either way this allows you to even switch between std::vector and std::map
as the container without modification the clients of GroupOfItems. In the
case of std::map you would redefine:

void GroupOfItems::ForEachItem( const ItemVisitor& aItemVisitor )
{
typedef std::map<...>::iterator tItr;

for_each( tItr lItr = m.begin() ; lItr != m.end(), ++lItr )
{
aItemVisitor( lItr->second );
}
}

Jeff Flinn
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top