By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,376 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

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

P: n/a
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.

Jul 23 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Ed wrote:
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
Jul 23 '05 #2

P: n/a
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

Jul 23 '05 #3

P: n/a

"Ed" <ed********@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
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
Jul 23 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.