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

stl containers style issue

P: n/a
Hello,

I've been getting into the STL lately for personal projects and I'm can't
decide whether to wrap containers or not. So the choice is whether to have
a member variable like this:

std::vector<Stuff> m_stuff;

Or to wrap it in a 'StuffVector' class, encapsulating operations on the
vector...

StuffVector m_stuff;

What do the STL aficionados out there prefer?

thanks.

Jul 22 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Hi,

"Glen Able" <re***********************@hoxtmxail.com> wrote in message
news:bp*******************@news.demon.co.uk...
Hello,

I've been getting into the STL lately for personal projects and I'm can't
decide whether to wrap containers or not. So the choice is whether to have a member variable like this:

std::vector<Stuff> m_stuff;
I would go for this, unless you want to use some methods specific for
std:vector<Stuff> (so not generic algoritms or standard vector methods) then
it would make sense to wrap it in a class with the methods.

Just my opinion,

Regards, Ron AF Greve
Or to wrap it in a 'StuffVector' class, encapsulating operations on the
vector...

StuffVector m_stuff;

What do the STL aficionados out there prefer?

thanks.

Jul 22 '05 #2

P: n/a
Moonlit wrote:
Hi,

"Glen Able" <re***********************@hoxtmxail.com> wrote in message
news:bp*******************@news.demon.co.uk...
Hello,

I've been getting into the STL lately for personal projects and I'm can't
decide whether to wrap containers or not. So the choice is whether to

have
a member variable like this:

std::vector<Stuff> m_stuff;


I would go for this, unless you want to use some methods specific for
std:vector<Stuff> (so not generic algoritms or standard vector methods)
then it would make sense to wrap it in a class with the methods.

Just my opinion,

Regards, Ron AF Greve

Or to wrap it in a 'StuffVector' class, encapsulating operations on the
vector...

StuffVector m_stuff;

What do the STL aficionados out there prefer?

thanks.


i'm not one of the aficionados, but the way i like is:

typedef std::vector<Stuff> StuffVector;

in a general header;
in Italy we say "you get one pigeon with two broad beans"
Jul 22 '05 #3

P: n/a
"Glen Able" <re***********************@hoxtmxail.com> wrote in message news:<bp*******************@news.demon.co.uk>...
Hello,

I've been getting into the STL lately for personal projects and I'm can't
decide whether to wrap containers or not. So the choice is whether to have
a member variable like this:

std::vector<Stuff> m_stuff;

Or to wrap it in a 'StuffVector' class, encapsulating operations on the
vector...

StuffVector m_stuff;

What do the STL aficionados out there prefer?


I generally limit my choices to either using the standard library
object directly,

typedef std::vector<Stuff> StuffBuff;

or wrapping the standard library container and forwarding the few
operations I believe necessary.

class StuffBuff
{
public:
void addStuff(const Stuff&);
void removeStuff(const Stuff&);
private:
typedef std::vector<Stuff> StuffContainer;
StuffContainer m_stuffContainer;
};

Which I choose depends on the application and what interface I want to
present.

I have generally found inheritance to be a useful tool of limited
application: the longer I have used C++, the less I am impressed by
class heirarchies of depth greater than 2 or 3. I have never found it
necessary to derive from standard library objects, with the, uh,
exception of std::exception-based classes and some IOStreams classes.

My rule of thumb says it's better to own (have as a member) than to
loan (borrow the interface of) a non-interface class.

--
Stephen M. Webb
Jul 22 '05 #4

P: n/a
"Glen Able" <re***********************@hoxtmxail.com> wrote in message news:<bp*******************@news.demon.co.uk>...
Hello,

I've been getting into the STL lately for personal projects and I'm can't
decide whether to wrap containers or not. So the choice is whether to have
a member variable like this:

std::vector<Stuff> m_stuff;

Or to wrap it in a 'StuffVector' class, encapsulating operations on the
vector...

StuffVector m_stuff;

What do the STL aficionados out there prefer?

thanks.


The operations on a vector are already encapsulated in the vector
class. That's the point. If m_stuff needs the behaviour of a
std::vector<Stuff> then you gain nothing by burying that behaviour in
a new type called StuffVector.

There might be times when you have a good reason to want a restricted
subset of the vector functionality. Or you want tighter constraints or
invariants than std::vector offers. In that case you could have a
StuffVector class, with a private std::vector<Stuff> member. Then you
could expose only the bits of the vector interface you need and
implement whatever constraints you need. But I don't think that's what
your question is getting at.

hth
GJD
Jul 22 '05 #5

P: n/a
Hi,

"cecconeurale" <fr****************@virgilio.it> wrote in message
news:bp**********@news.flashnet.it...
Moonlit wrote:
Hi,

"Glen Able" <re***********************@hoxtmxail.com> wrote in message
news:bp*******************@news.demon.co.uk...
Hello,

I've been getting into the STL lately for personal projects and I'm can't decide whether to wrap containers or not. So the choice is whether to have
a member variable like this:

std::vector<Stuff> m_stuff;


I would go for this, unless you want to use some methods specific for
std:vector<Stuff> (so not generic algoritms or standard vector methods)
then it would make sense to wrap it in a class with the methods.

Just my opinion,

Regards, Ron AF Greve

Or to wrap it in a 'StuffVector' class, encapsulating operations on the
vector...

StuffVector m_stuff;

What do the STL aficionados out there prefer?

thanks.


i'm not one of the aficionados, but the way i like is:

typedef std::vector<Stuff> StuffVector;


Yes, that saves a bit of time when to occasional 'I wanted a car, but now
you have built it I would prefer an aeroplane. Not that much work is it? You
only have to glue on some wings, I guess?' happens.

However I personally do not use the typedef for this, I like to be reminded
in the code what the type actually is, but many developers do it your way,

Regards, Ron AF Greve.
in a general header;
in Italy we say "you get one pigeon with two broad beans"

Jul 22 '05 #6

P: n/a
Thanks to all the respondents for some interesting perspectives!

I've concluded that I'll just do a typedef in most cases, simply because I
find it easier to mentally parse 'StuffVector' rather than
'std::vector<Stuff>'.
I feel similarly to you here, Stephen:
I have generally found inheritance to be a useful tool of limited
application: the longer I have used C++, the less I am impressed by
class heirarchies of depth greater than 2 or 3.
But I'm wondering why you say this:
My rule of thumb says it's better to own (have as a member) than to
loan (borrow the interface of) a non-interface class.


In the case where I want to extend the functionality e.g. add some method
like StuffVector::FindTheBestStuff(), I'm still not keen on creating a
simple wrapper class, because it's such a pain to then have to wrap all the
vector::begin() type stuff where that's required. Isn't it natural here to
derive StuffVector from std::vector<Stuff> and add whatever else I need?

thanks.

Jul 22 '05 #7

P: n/a
Moonlit wrote:
Hi,

"cecconeurale" <fr****************@virgilio.it> wrote in message
news:bp**********@news.flashnet.it...
Moonlit wrote:
> Hi,
>
> "Glen Able" <re***********************@hoxtmxail.com> wrote in message
> news:bp*******************@news.demon.co.uk...
>> Hello,
>>
>> I've been getting into the STL lately for personal projects and I'm can't >> decide whether to wrap containers or not. So the choice is whether to
> have
>> a member variable like this:
>>
>> std::vector<Stuff> m_stuff;
>
> I would go for this, unless you want to use some methods specific for
> std:vector<Stuff> (so not generic algoritms or standard vector methods)
> then it would make sense to wrap it in a class with the methods.
>
> Just my opinion,
>
> Regards, Ron AF Greve
>>
>> Or to wrap it in a 'StuffVector' class, encapsulating operations on
>> the vector...
>>
>> StuffVector m_stuff;
>>
>> What do the STL aficionados out there prefer?
>>
>> thanks.
>>
>>
>>
i'm not one of the aficionados, but the way i like is:

typedef std::vector<Stuff> StuffVector;


Yes, that saves a bit of time when to occasional 'I wanted a car, but now
you have built it I would prefer an aeroplane. Not that much work is it?
You only have to glue on some wings, I guess?' happens.


Well, here is how I glue on wings to my car:

typedef std::vector<Stuff> car;

class airplane : public car {
...
}

I really don't know if this is a way out or simply a mess. However ... It
works. I think it's like specialyzing the template. Obviously you cannot go
back and make a F1 car from an airplane.

bye.
However I personally do not use the typedef for this, I like to be
reminded in the code what the type actually is, but many developers do it
your way,

Regards, Ron AF Greve.

in a general header;
in Italy we say "you get one pigeon with two broad beans"

Jul 22 '05 #8

P: n/a
"Glen Able" <re***********************@hoxtmxail.com> wrote in message news:<bp*******************@news.demon.co.uk>...
Thanks to all the respondents for some interesting perspectives!

I've concluded that I'll just do a typedef in most cases, simply because I
find it easier to mentally parse 'StuffVector' rather than
'std::vector<Stuff>'.
I feel similarly to you here, Stephen:
I have generally found inheritance to be a useful tool of limited
application: the longer I have used C++, the less I am impressed by
class heirarchies of depth greater than 2 or 3.


But I'm wondering why you say this:
My rule of thumb says it's better to own (have as a member) than to
loan (borrow the interface of) a non-interface class.


In the case where I want to extend the functionality e.g. add some method
like StuffVector::FindTheBestStuff(), I'm still not keen on creating a
simple wrapper class, because it's such a pain to then have to wrap all the
vector::begin() type stuff where that's required. Isn't it natural here to
derive StuffVector from std::vector<Stuff> and add whatever else I need?


First of all, hopefully you are aware that std::vector does not have a
virtual destructor, so you would have to make sure you never deleted a
StuffVector polymorphically. ie

std::vector<Stuff>* p = new StuffVector;
delete p; // undefined behaviour, never do this !!

This is not a reason to never derive from std containers, but it's
something you need to know.

To answer your question, presumably your implementation of
StuffVector::FindTheBestStuff() would only use the public interface of
the std::vector<Stuff> base class (there is no protected interface and
you can't get at the private bits). In which case I think the natural
solution is to implement FindTheBestStuff as a free-standing function
that takes a std::vector<Stuff> (probably by const reference) plus any
other parameters it needs and returns whatever
StuffVector::FindTheBestStuff() would have returned.

You might be interested to read this article by Scott Meyers about
free standing functions and encapsulation. I came across it after
finishing a project where I had decided go down the route equivalent
to having a StuffVector class with a std::vector<Stuff> member. During
the course of the project my design had crumbled around me somewhat,
and the code had got hideously monolithic (and I don't think the
inheritance solution would have helped). I seriously wished I had read
the article before I started.

http://www.cuj.com/documents/s=8042/cuj0002meyers/

--
hth
GJD
Jul 22 '05 #9

P: n/a
Hi,

"cecconeurale" <fr****************@virgilio.it> wrote in message
news:bp**********@news.flashnet.it...
Moonlit wrote:
Hi,

"cecconeurale" <fr****************@virgilio.it> wrote in message
news:bp**********@news.flashnet.it...
Moonlit wrote:

> Hi,
>
> "Glen Able" <re***********************@hoxtmxail.com> wrote in message > news:bp*******************@news.demon.co.uk...
>> Hello,
>>
>> I've been getting into the STL lately for personal projects and I'm can't
>> decide whether to wrap containers or not. So the choice is whether to > have
>> a member variable like this:
>>
>> std::vector<Stuff> m_stuff;
>
> I would go for this, unless you want to use some methods specific for
> std:vector<Stuff> (so not generic algoritms or standard vector methods) > then it would make sense to wrap it in a class with the methods.
>
> Just my opinion,
>
> Regards, Ron AF Greve
>>
>> Or to wrap it in a 'StuffVector' class, encapsulating operations on
>> the vector...
>>
>> StuffVector m_stuff;
>>
>> What do the STL aficionados out there prefer?
>>
>> thanks.
>>
>>
>>

i'm not one of the aficionados, but the way i like is:

typedef std::vector<Stuff> StuffVector;


Yes, that saves a bit of time when to occasional 'I wanted a car, but now you have built it I would prefer an aeroplane. Not that much work is it?
You only have to glue on some wings, I guess?' happens.


Well, here is how I glue on wings to my car:

typedef std::vector<Stuff> car;

class airplane : public car {
...
}

Hmmm, I can drive my car through a carwash, I think I will loose the wings
if I do the same with an earoplane (so an aeroplane appears not to be a
car.)

I really don't know if this is a way out or simply a mess. However ... It It becomes a mess at the carwash ;-0

works. I think it's like specialyzing the template. Obviously you cannot go back and make a F1 car from an airplane.
Regards, Ron AF Greve.
bye.
However I personally do not use the typedef for this, I like to be
reminded in the code what the type actually is, but many developers do it your way,

Regards, Ron AF Greve.

in a general header;
in Italy we say "you get one pigeon with two broad beans"


Jul 22 '05 #10

P: n/a
"Glen Able" <re***********************@hoxtmxail.com> wrote in message news:<bp*******************@news.demon.co.uk>...
Thanks to all the respondents for some interesting perspectives!
But I'm wondering why you say this:
My rule of thumb says it's better to own (have as a member) than to
loan (borrow the interface of) a non-interface class.


In the case where I want to extend the functionality e.g. add some method
like StuffVector::FindTheBestStuff(), I'm still not keen on creating a
simple wrapper class, because it's such a pain to then have to wrap all the
vector::begin() type stuff where that's required. Isn't it natural here to
derive StuffVector from std::vector<Stuff> and add whatever else I need?


I have found the key to good code is to keep it simple. A function
should do one thing and one thing only: a class should represent one
concept and one concept only. In the case of a container class, it
contains things. What you do with those things is a separate concept
and so should not be a part of the container class. You will notice
the standard library is (mostly) structured that way, the exceptions
being special optimization cases. Algorithms that operate on
containers (such as FindTheBestStuff()) are separate from the
containers themselves.

Only classes that have limited interfaces to their contained data are
good candidates for wrapping standard containers. For example, the
standard stack class wraps its container. If you need the container
to expose a more generalized interface and you want to add specific
functions based on that interface, derivation isn't superior to a
separate function, since despite having access to the container's
internals you don't want to write code that depends on the container's
implementation anyway. Since the standard containers don't have
virtual destructors, derivation is actually inferior.

--
Stephen M. Webb
Jul 22 '05 #11

P: n/a
Moonlit wrote:
"cecconeurale" <fr****************@virgilio.it> wrote in message
news:bp**********@news.flashnet.it...

i'm not one of the aficionados, but the way i like is:

typedef std::vector<Stuff> StuffVector;

Yes, that saves a bit of time when to occasional 'I wanted a car, but now
you have built it I would prefer an aeroplane. Not that much work is it? You
only have to glue on some wings, I guess?' happens.

However I personally do not use the typedef for this, I like to be reminded
in the code what the type actually is, but many developers do it your way,


I'd agree with those sentiments.

I think that the justification used for

typedef std::vector<Stuff> StuffVector;

is that a later date you might want to replace

std::vector<Stuff>

with some other contain that has a similar interface:

our::paged_array<Stuff>

without having to trawl the code replacing std::vector with
our::paged_array. However, this never quite works because
users will inevitably know that they are dealing with
std::vector and that knowledge will permeate through the
codebase.

If someone really wants to isolate the fact that they are
using std::vector then they should use containment.

Jul 22 '05 #12

P: n/a
Glen Able wrote:
I've been getting into the STL lately for personal projects
and I'm can't decide whether to wrap containers or not.
So the choice is whether to have a member variable like this:

std::vector<Stuff> m_stuff;

Or to wrap it in a 'StuffVector' class,

StuffVector m_stuff;

encapsulating operations on the vector...
What do the STL aficionados out there prefer?


It doesn't matter unless you need to return a reference to m_stuff.
You can do this:

class myClass {
public:
typedef std::vector<Stuff> StuffVector;
private:
StuffVector m_stuff;
public:
StuffVector& stuff(void) {
return mstuff;
}
// . . .
};

int main(int argc, char* argv[]) {
myClass m;
m.stuff()[0] = Stuff();
return 0;
}

Jul 22 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.