Sign in with
Sign up | Sign in
Your question

About putting different types of objects on std::list

Last response: in Video Games
Share
Anonymous
June 20, 2005 2:56:41 PM

Archived from groups: rec.games.roguelike.development (More info?)

When writing item handling code I encountered a problem that is
probably pretty common to object-oriented roguelikes.

For now my item handling classes include a generic Item class, and
Container, inheriting from it. Obviously I would like a Container
object to contain other items. For this purpose I'm using
std::list.

So my first idea was to do list<Item> l, or something similar.
A good c++ programmer (which I am not) will probably recognize
the problem that this causes - when I put a Container object
on such list, it gets reduced to an Item, all its methods being
substituted by ones from the Item class.

The easiest solution to this is using list<Item*>, but it brings
another problem, namely the destructor of std::list leaving
all the items in memory. I could delete them in the destructor
of the class that contains the list, but it wouldn't be too
elegant.

I could write a pointer_list<foo> class, which would use std::list
to store pointers to foo and delete them upon destruction. But
I would have to implement the numerous methods of std::list that
I'd like to use.

I concluded that I should make a pointer<foo> object that would
store a pointer to foo and have a destructor that deletes it.
But this brings a different problem (maybe less obvious), that
(for example) std::list<foo>::p ush_back() takes the value of the
parameter, and thus uses the copying constructor. So we get two
"pointers" pointing at the same place, one of which might get
deleted after a while, thus freeing the memory that the other is
pointing to.

At this point I wanted to call for help on this group, but then
I had an idea to have a counter in each item that tells how many
"pointers" are pointing at it, destructors decreasing it, and
copying constructors increasing. When it comes to 0, the item
can be deleted.

So what do you guys think of this? Is the last solution optimal,
or are there others, which I haven't thought about?

Thanks for any help,
Michal Brzozowski
Anonymous
June 20, 2005 3:46:14 PM

Archived from groups: rec.games.roguelike.development (More info?)

Michal Brzozowski wrote:
> When writing item handling code I encountered a problem that is
> probably pretty common to object-oriented roguelikes.
>
> For now my item handling classes include a generic Item class, and
> Container, inheriting from it. Obviously I would like a Container
> object to contain other items. For this purpose I'm using
> std::list.
>
> So my first idea was to do list<Item> l, or something similar.
> A good c++ programmer (which I am not) will probably recognize
> the problem that this causes - when I put a Container object
> on such list, it gets reduced to an Item, all its methods being
> substituted by ones from the Item class.
>
> The easiest solution to this is using list<Item*>, but it brings
> another problem, namely the destructor of std::list leaving
> all the items in memory. I could delete them in the destructor
> of the class that contains the list, but it wouldn't be too
> elegant.

If you cared about elegance, you are using the wrong language :>

I'd go with this approach and just delete the individual items in the
destructor of the class that owns the list. I really don't like the
idea of the list actually containing the Item class itself rather than
a pointer to it.

Mind you, I'd also avoid STL like the plague and write my own list
class from scratch, so I may not be the best source of advice.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
Anonymous
June 20, 2005 5:07:13 PM

Archived from groups: rec.games.roguelike.development (More info?)

John wrote:
> On 2005-06-20, Jeff Lait <torespondisfutile@hotmail.com> wrote:
>
> > I'd go with this approach and just delete the individual items in the
> > destructor of the class that owns the list. I really don't like the
> > idea of the list actually containing the Item class itself rather than
> > a pointer to it.
>
> With inheritance heirarchies and the STL containers you pretty much have
> to use a smart pointer class and put those into the container. I would use
> the boost smart pointer (http://www.boost.org/libs/smart_ptr/smart_ptr.htm)
> both because it works and because the recent addition of smart pointers
> to the C++ standard is essentially an exact copy of the boost smart
> pointer. Makes a good placeholder until compilers catch up with the
> standard.

Why wouldn't just using regular pointers and having another class
assume ownership work? Ie, the list<item *> approach?
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
Related resources
Can't find your answer ? Ask !
Anonymous
June 20, 2005 6:13:45 PM

Archived from groups: rec.games.roguelike.development (More info?)

Christophe Cavalaria wrote:
> Jeff Lait wrote:
>
> > John wrote:
> >> On 2005-06-20, Jeff Lait <torespondisfutile@hotmail.com> wrote:
> >>
> >> > I'd go with this approach and just delete the individual items in the
> >> > destructor of the class that owns the list. I really don't like the
> >> > idea of the list actually containing the Item class itself rather than
> >> > a pointer to it.
> >>
> >> With inheritance heirarchies and the STL containers you pretty much have
> >> to use a smart pointer class and put those into the container. I would
> >> use the boost smart pointer
> >> (http://www.boost.org/libs/smart_ptr/smart_ptr.htm) both because it works
> >> and because the recent addition of smart pointers to the C++ standard is
> >> essentially an exact copy of the boost smart pointer. Makes a good
> >> placeholder until compilers catch up with the standard.
> >
> > Why wouldn't just using regular pointers and having another class
> > assume ownership work? Ie, the list<item *> approach?
>
> Slightly less work on the part of the programmer. Less work and less code to
> write usualy means less mistakes :) 

While it would require more work to use the smart pointers (if I were
to
implement them myself), once I've done it, I can forget about it.
If I have to remember to delete the objects on the list before deleting
the list, then it's almost guaranteed that I will forget it at some
place :) .

On the other hand, it wouldn't be too harmful to leave the objects in
memory, as long as I don't have 100 000 items in my game :) .

Btw, I think Ocaml uses the approach "if it uses too much memory,
clean it up". So maybe running the garbage collector once in a while
is a better solution than counting what pointers point to what objects
:-).
Anonymous
June 20, 2005 8:04:51 PM

Archived from groups: rec.games.roguelike.development (More info?)

Many people are complaining about the uglyness if C++, but it only gets
ugly if you don't know what you're doing, especially since plenty of
people have elegantly implemented containers and item lists.

You could also make a class Inventory (or ItemList) and have Container
inherit both that and Item.

It's hard to answer questions like this without knowing exactly what you
want to do. What's wrong with using list<Item *> and destroying the
items when you destroy the container? And why would you destroy the
container?

--
Jim Strathmeyer
June 20, 2005 10:19:24 PM

Archived from groups: rec.games.roguelike.development (More info?)

Michal Brzozowski wrote:
> When writing item handling code I encountered a problem that is
> probably pretty common to object-oriented roguelikes.
>
> For now my item handling classes include a generic Item class, and
> Container, inheriting from it. Obviously I would like a Container
> object to contain other items. For this purpose I'm using
> std::list.
>
> So my first idea was to do list<Item> l, or something similar.
> A good c++ programmer (which I am not) will probably recognize
> the problem that this causes - when I put a Container object
> on such list, it gets reduced to an Item, all its methods being
> substituted by ones from the Item class.
>
> The easiest solution to this is using list<Item*>, but it brings
> another problem, namely the destructor of std::list leaving
> all the items in memory. I could delete them in the destructor
> of the class that contains the list, but it wouldn't be too
> elegant.

Yes, list<Item*> is a good way to go. If you're worried about freeing
the items, then delete them in the Container destructor. (Bearing in
mind that you should only do this if the items have actually been
destroyed with the container. If the item has been removed from the
container and now resides somewhere else, you don't want to delete it!)

> I concluded that I should make a pointer<foo> object that would
> store a pointer to foo and have a destructor that deletes it.

Nope, I don't think this is a good idea

> At this point I wanted to call for help on this group, but then
> I had an idea to have a counter in each item that tells how many
> "pointers" are pointing at it, destructors decreasing it, and
> copying constructors increasing. When it comes to 0, the item
> can be deleted.

Ugh! No, don't do this.

A.
June 20, 2005 10:28:33 PM

Archived from groups: rec.games.roguelike.development (More info?)

Antoine wrote:
> Michal Brzozowski wrote:
> > When writing item handling code I encountered a problem that is
> > probably pretty common to object-oriented roguelikes.
> >
> > For now my item handling classes include a generic Item class, and
> > Container, inheriting from it. Obviously I would like a Container
> > object to contain other items. For this purpose I'm using
> > std::list.
> >
> > So my first idea was to do list<Item> l, or something similar.
> > A good c++ programmer (which I am not) will probably recognize
> > the problem that this causes - when I put a Container object
> > on such list, it gets reduced to an Item, all its methods being
> > substituted by ones from the Item class.
> >
> > The easiest solution to this is using list<Item*>, but it brings
> > another problem, namely the destructor of std::list leaving
> > all the items in memory. I could delete them in the destructor
> > of the class that contains the list, but it wouldn't be too
> > elegant.
>
> Yes, list<Item*> is a good way to go. If you're worried about freeing
> the items, then delete them in the Container destructor. (Bearing in
> mind that you should only do this if the items have actually been
> destroyed with the container. If the item has been removed from the
> container and now resides somewhere else, you don't want to delete it!)
>
> > I concluded that I should make a pointer<foo> object that would
> > store a pointer to foo and have a destructor that deletes it.
>
> Nope, I don't think this is a good idea
>
> > At this point I wanted to call for help on this group, but then
> > I had an idea to have a counter in each item that tells how many
> > "pointers" are pointing at it, destructors decreasing it, and
> > copying constructors increasing. When it comes to 0, the item
> > can be deleted.
>
> Ugh! No, don't do this.

Or if you do do it, don't reinvent the wheel - use a 'smart pointer'
(see previous posts) that supports 'reference counting'

A.
Anonymous
June 20, 2005 11:10:51 PM

Archived from groups: rec.games.roguelike.development (More info?)

Jim Strathmeyer wrote:
> Also, FWIW, IMHO, I don't feel that smart pointers are necessary here.
> When it comes to things like items and monsters, you know when they're
> created and destroyed, and trying to use one after they're destroyed
> should be an error.
>
> Smart pointers/reference counting leads to lazy and bad programming.

Agreed. However, it would be easier to agree with you if you quoted
the relevant passages of the earlier messages :>

One important thing to note about Item is that it is very important to
answer the ownership question. When you go to write your save/load
routines, things will be much simpler if you have a clear sense of what
structure owns the Item at any given moment.

Note that, depending on the smart pointer implementation, you can have
the ability to still explicitly delete the object and have all dangling
pointers become null automagically. I use a variant of this for
handling pointers to creatures. Well, not pointers, but 16 bit indices
as I'm not willing to sacrifice 2 bytes as readily as most on r.g.r.d
:>

This way, creatures can track their current target, for example,
without having to be notified if the target is deleted.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
Anonymous
June 21, 2005 12:43:06 AM

Archived from groups: rec.games.roguelike.development (More info?)

Also, FWIW, IMHO, I don't feel that smart pointers are necessary here.
When it comes to things like items and monsters, you know when they're
created and destroyed, and trying to use one after they're destroyed
should be an error.

Smart pointers/reference counting leads to lazy and bad programming.

--
Jim Strathmeyer
Anonymous
June 21, 2005 12:51:42 AM

Archived from groups: rec.games.roguelike.development (More info?)

Jeff Lait wrote:

> Michal Brzozowski wrote:
>> When writing item handling code I encountered a problem that is
>> probably pretty common to object-oriented roguelikes.
>>
>> For now my item handling classes include a generic Item class, and
>> Container, inheriting from it. Obviously I would like a Container
>> object to contain other items. For this purpose I'm using
>> std::list.
>>
>> So my first idea was to do list<Item> l, or something similar.
>> A good c++ programmer (which I am not) will probably recognize
>> the problem that this causes - when I put a Container object
>> on such list, it gets reduced to an Item, all its methods being
>> substituted by ones from the Item class.
>>
>> The easiest solution to this is using list<Item*>, but it brings
>> another problem, namely the destructor of std::list leaving
>> all the items in memory. I could delete them in the destructor
>> of the class that contains the list, but it wouldn't be too
>> elegant.

This is an ownership issue. If you decide that the container must be the
owner of the object, then you can create an ItemContainer class with a
list<Item*> member which will delete each items in the list when it goes
out of scope. Or you could try using a smartptr. Check boost.org for that
one.

I don't see many good reasons why your list<Item*> shouldn't be encapsulated
somewhere inside another object which knows what to do with it :) 

> If you cared about elegance, you are using the wrong language :>
>
> I'd go with this approach and just delete the individual items in the
> destructor of the class that owns the list. I really don't like the
> idea of the list actually containing the Item class itself rather than
> a pointer to it.
>
> Mind you, I'd also avoid STL like the plague and write my own list
> class from scratch, so I may not be the best source of advice.

STL has it's problems but writing a list from scratch each time is hardly a
good solution :/ 
Anonymous
June 21, 2005 2:21:32 AM

Archived from groups: rec.games.roguelike.development (More info?)

Jeff Lait wrote:

> John wrote:
>> On 2005-06-20, Jeff Lait <torespondisfutile@hotmail.com> wrote:
>>
>> > I'd go with this approach and just delete the individual items in the
>> > destructor of the class that owns the list. I really don't like the
>> > idea of the list actually containing the Item class itself rather than
>> > a pointer to it.
>>
>> With inheritance heirarchies and the STL containers you pretty much have
>> to use a smart pointer class and put those into the container. I would
>> use the boost smart pointer
>> (http://www.boost.org/libs/smart_ptr/smart_ptr.htm) both because it works
>> and because the recent addition of smart pointers to the C++ standard is
>> essentially an exact copy of the boost smart pointer. Makes a good
>> placeholder until compilers catch up with the standard.
>
> Why wouldn't just using regular pointers and having another class
> assume ownership work? Ie, the list<item *> approach?

Slightly less work on the part of the programmer. Less work and less code to
write usualy means less mistakes :) 
Anonymous
June 21, 2005 3:20:37 AM

Archived from groups: rec.games.roguelike.development (More info?)

Michal Brzozowski wrote:

>
>
> Christophe Cavalaria wrote:
>> Jeff Lait wrote:
>>
>> > John wrote:
>> >> On 2005-06-20, Jeff Lait <torespondisfutile@hotmail.com> wrote:
>> >>
>> >> > I'd go with this approach and just delete the individual items in
>> >> > the
>> >> > destructor of the class that owns the list. I really don't like
>> >> > the idea of the list actually containing the Item class itself
>> >> > rather than a pointer to it.
>> >>
>> >> With inheritance heirarchies and the STL containers you pretty much
>> >> have to use a smart pointer class and put those into the container. I
>> >> would use the boost smart pointer
>> >> (http://www.boost.org/libs/smart_ptr/smart_ptr.htm) both because it
>> >> works and because the recent addition of smart pointers to the C++
>> >> standard is essentially an exact copy of the boost smart pointer.
>> >> Makes a good placeholder until compilers catch up with the standard.
>> >
>> > Why wouldn't just using regular pointers and having another class
>> > assume ownership work? Ie, the list<item *> approach?
>>
>> Slightly less work on the part of the programmer. Less work and less code
>> to write usualy means less mistakes :) 
>
> While it would require more work to use the smart pointers (if I were
> to
> implement them myself), once I've done it, I can forget about it.
> If I have to remember to delete the objects on the list before deleting
> the list, then it's almost guaranteed that I will forget it at some
> place :) .
>
> On the other hand, it wouldn't be too harmful to leave the objects in
> memory, as long as I don't have 100 000 items in my game :) .
>
> Btw, I think Ocaml uses the approach "if it uses too much memory,
> clean it up". So maybe running the garbage collector once in a while
> is a better solution than counting what pointers point to what objects
> :-).

garbage collectors make destructors unreliable. destructors are good for
RAII which is a development paradigm used to manage in an efficient and
safe way all ressource allocation. GC only work for memory allocation and
does nothing to help you with mutexes, file handles etc...
Anonymous
June 21, 2005 5:33:59 AM

Archived from groups: rec.games.roguelike.development (More info?)

Antoine wrote:
[...]
> Yes, list<Item*> is a good way to go. If you're worried about freeing
> the items, then delete them in the Container destructor. (Bearing in
> mind that you should only do this if the items have actually been
> destroyed with the container. If the item has been removed from the
> container and now resides somewhere else, you don't want to delete it!)

I don't think that, in general, containers and inventory should own
Item object references: they belong in global game state because they
are one of the things that must be remembered in saved games and last
forever.

An Item can be in a number of places and states like

wielded by character
wielded by monster
backpack
monster backpack
corpse
nested container
floor
pile on floor

Let's make all these Place objects: an Item is in one Place, a Place
usually contains more Items. Both relations are of association, not
ownership: the lifetimes of Places and Items are completely independent
except in specific cases of the game rules.
I suggest using a pointer from the Item to its Place (null if the Item
is "nowhere") in addition to the index of Items in each Place.
When Item objects are deleted (individual use or destruction, level
change etc.) they can invalidate or update the list<Item*> or
set<Item*> of every Item in their referenced Place.
Conversely on Place deletion (level change, monster death etc.) the
Place can be responsible for moving Items to another Place (e.g. from
monster to floor) or rarely deleting them.

Lorenzo Gatti
Anonymous
June 21, 2005 1:07:24 PM

Archived from groups: rec.games.roguelike.development (More info?)

John wrote:
> On Jim Strathmeyer <strathWHATEVERIGETENOUGHSPAMANYWAYS@ipass.net> wrote:
> > Smart pointers/reference counting leads to lazy and bad programming.
>
> Wow. That statement is just stupid. I hope you aren't a professional
> programmer and if you are I hope I never use anything you write.

Narrowmindedness is an occupational hazard of programming.

Could we also please dial back the ad hominem a bit? Saying the
statement is "just stupid" is harsh, but fine. I am not sure we should
be making accusations about people's professional life based on USENET
postings.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
Anonymous
June 21, 2005 3:27:19 PM

Archived from groups: rec.games.roguelike.development (More info?)

This day of 21 Jun 2005 09:07:24 -0700, "Jeff Lait"
<torespondisfutile@hotmail.com> saw fit to scribe:

>John wrote:
>> On Jim Strathmeyer <strathWHATEVERIGETENOUGHSPAMANYWAYS@ipass.net> wrote:
>> > Smart pointers/reference counting leads to lazy and bad programming.
>>
>> Wow. That statement is just stupid. I hope you aren't a professional
>> programmer and if you are I hope I never use anything you write.
>
>Narrowmindedness is an occupational hazard of programming.
>
>Could we also please dial back the ad hominem a bit? Saying the
>statement is "just stupid" is harsh, but fine. I am not sure we should
>be making accusations about people's professional life based on USENET
>postings.

I must admit to feeling my eyebrows rise when I see you engaging in ad
hominem and then wishing it were used less. :-)

--
David C. Haley
http://david.the-haleys.org
Anonymous
June 21, 2005 3:32:54 PM

Archived from groups: rec.games.roguelike.development (More info?)

This day of 20 Jun 2005 10:56:41 -0700, "Michal Brzozowski"
<rusolis@poczta.fm> saw fit to scribe:

>When writing item handling code I encountered a problem that is
>probably pretty common to object-oriented roguelikes.
>
>For now my item handling classes include a generic Item class, and
>Container, inheriting from it. Obviously I would like a Container
>object to contain other items. For this purpose I'm using
>std::list.
>
>So my first idea was to do list<Item> l, or something similar.
>A good c++ programmer (which I am not) will probably recognize
>the problem that this causes - when I put a Container object
>on such list, it gets reduced to an Item, all its methods being
>substituted by ones from the Item class.
>
>The easiest solution to this is using list<Item*>, but it brings
>another problem, namely the destructor of std::list leaving
>all the items in memory. I could delete them in the destructor
>of the class that contains the list, but it wouldn't be too
>elegant.
>
>I could write a pointer_list<foo> class, which would use std::list
>to store pointers to foo and delete them upon destruction. But
>I would have to implement the numerous methods of std::list that
>I'd like to use.

Why not subclass off of std::list, out of curiosity?


>I concluded that I should make a pointer<foo> object that would
>store a pointer to foo and have a destructor that deletes it.
>But this brings a different problem (maybe less obvious), that
>(for example) std::list<foo>::p ush_back() takes the value of the
>parameter, and thus uses the copying constructor. So we get two
>"pointers" pointing at the same place, one of which might get
>deleted after a while, thus freeing the memory that the other is
>pointing to.

The std::auto_ptr is like this but it's smart enough to manage copy
constructors. It's basically what you describe, except that it correctly
manages transfer of ownership and all that good stuff. Check out the
following for a simple example:

http://www.josuttis.com/libbook/util/autoptr1.cpp.html
http://www.josuttis.com/libbook/util/autoptr2.cpp.html

His book gives an excellent explanation of where to use these and this
seems to be one of those cases.


>At this point I wanted to call for help on this group, but then
>I had an idea to have a counter in each item that tells how many
>"pointers" are pointing at it, destructors decreasing it, and
>copying constructors increasing. When it comes to 0, the item
>can be deleted.

Reference counting seems like huge overkill to me in a case like this,
where all you really want is a list that owns its contents and that
removes them (one way or another) when the list goes away.


>So what do you guys think of this? Is the last solution optimal,
>or are there others, which I haven't thought about?

If I were you, I'd take a good look at the auto_ptr, and then, I'd think
about subclassing off of std::list (although that could have some
'interesting' consequences). Failing that, if auto_ptr isn't quite right
for you, I'd try writing your own auto_ptr variant. The very, very last
thing I would do is reference counting, unless your project has some
important other need for it.

--
David C. Haley
http://david.the-haleys.org
Anonymous
June 21, 2005 3:36:15 PM

Archived from groups: rec.games.roguelike.development (More info?)

Jim Strathmeyer wrote:
>
> Smart pointers/reference counting leads to lazy and bad programming.
>

I wouldn't go that far. It is a tool, like anything else. If someone
thinks that a smart-pointer is a cure-all, then yes, it would lead to
lazy and bad programming. It has limitations.

If it's used as a tool, with certain requirements and effects though,
it can be a very nice design choice. If the rest of the app is
designed with it's use in mind, and enfoced to a point (ownership when
created ONLY, not allowing non-referenced pointers, etc), then you are
free to not be concerned with the problem anymore. The compiler will
stop the coder from doing anything unwanted.

It's really the same as having an owning object be responsible for
child's destruction, it's just generalized to the point where it could
be reused in any app w/out having to re-implement it. It also helps
catching the problems at compile-time.
Anonymous
June 21, 2005 3:58:02 PM

Archived from groups: rec.games.roguelike.development (More info?)

David Haley wrote:
> This day of 21 Jun 2005 09:07:24 -0700, "Jeff Lait"
> <torespondisfutile@hotmail.com> saw fit to scribe:
>
> >John wrote:
> >> On Jim Strathmeyer <strathWHATEVERIGETENOUGHSPAMANYWAYS@ipass.net> wrote:
> >> > Smart pointers/reference counting leads to lazy and bad programming.
> >>
> >> Wow. That statement is just stupid. I hope you aren't a professional
> >> programmer and if you are I hope I never use anything you write.
> >
> >Narrowmindedness is an occupational hazard of programming.
> >
> >Could we also please dial back the ad hominem a bit? Saying the
> >statement is "just stupid" is harsh, but fine. I am not sure we should
> >be making accusations about people's professional life based on USENET
> >postings.
>
> I must admit to feeling my eyebrows rise when I see you engaging in ad
> hominem and then wishing it were used less. :-)

My apologies if that seemed to be an attack directly on John. I was
trying to comment on this debate as a whole. I would quite readily
include myself in the programming-induced narrowmindedness department.

I can see why it would look like it was directed at John alone, but I
also meant it to apply to Jim's statement, and also my original quick
quip which started us in this direction.
--
Jeff Lait
(POWDER: http://www.zincland.com/powder)
June 21, 2005 7:11:17 PM

Archived from groups: rec.games.roguelike.development (More info?)

On Jim Strathmeyer <strathWHATEVERIGETENOUGHSPAMANYWAYS@ipass.net> wrote:
> Smart pointers/reference counting leads to lazy and bad programming.

Wow. That statement is just stupid. I hope you aren't a professional
programmer and if you are I hope I never use anything you write.
Anonymous
June 22, 2005 12:59:58 AM

Archived from groups: rec.games.roguelike.development (More info?)

David Haley wrote:

> This day of 20 Jun 2005 10:56:41 -0700, "Michal Brzozowski"
> <rusolis@poczta.fm> saw fit to scribe:
>
>>When writing item handling code I encountered a problem that is
>>probably pretty common to object-oriented roguelikes.
>>
>>For now my item handling classes include a generic Item class, and
>>Container, inheriting from it. Obviously I would like a Container
>>object to contain other items. For this purpose I'm using
>>std::list.
>>
>>So my first idea was to do list<Item> l, or something similar.
>>A good c++ programmer (which I am not) will probably recognize
>>the problem that this causes - when I put a Container object
>>on such list, it gets reduced to an Item, all its methods being
>>substituted by ones from the Item class.
>>
>>The easiest solution to this is using list<Item*>, but it brings
>>another problem, namely the destructor of std::list leaving
>>all the items in memory. I could delete them in the destructor
>>of the class that contains the list, but it wouldn't be too
>>elegant.
>>
>>I could write a pointer_list<foo> class, which would use std::list
>>to store pointers to foo and delete them upon destruction. But
>>I would have to implement the numerous methods of std::list that
>>I'd like to use.
>
> Why not subclass off of std::list, out of curiosity?

Subclassing of the stl types is a bad idea in the first place. Why would you
do that anyway ? Is there some fundamental reason why the container object
must be a std::list ? If not, then don't bother it'll only cause
problems :)  Remember, inheritance is the strongest relation between 2
classes you can create in C++ and it is more than often too much.

>>I concluded that I should make a pointer<foo> object that would
>>store a pointer to foo and have a destructor that deletes it.
>>But this brings a different problem (maybe less obvious), that
>>(for example) std::list<foo>::p ush_back() takes the value of the
>>parameter, and thus uses the copying constructor. So we get two
>>"pointers" pointing at the same place, one of which might get
>>deleted after a while, thus freeing the memory that the other is
>>pointing to.
>
> The std::auto_ptr is like this but it's smart enough to manage copy
> constructors. It's basically what you describe, except that it correctly
> manages transfer of ownership and all that good stuff. Check out the
> following for a simple example:
>
> http://www.josuttis.com/libbook/util/autoptr1.cpp.html
> http://www.josuttis.com/libbook/util/autoptr2.cpp.html
>
> His book gives an excellent explanation of where to use these and this
> seems to be one of those cases.

auto_ptr was a bad idea in the first place. They have a lot of issues with
their weird ownership transfert paradigm. Also, it goes against point 8 of
the "Effective STL" of Scott Meyers. Point 8 is : "Never create containers
of auto_ptrs" :) 

>>At this point I wanted to call for help on this group, but then
>>I had an idea to have a counter in each item that tells how many
>>"pointers" are pointing at it, destructors decreasing it, and
>>copying constructors increasing. When it comes to 0, the item
>>can be deleted.
>
> Reference counting seems like huge overkill to me in a case like this,
> where all you really want is a list that owns its contents and that
> removes them (one way or another) when the list goes away.
>
>
>>So what do you guys think of this? Is the last solution optimal,
>>or are there others, which I haven't thought about?
>
> If I were you, I'd take a good look at the auto_ptr, and then, I'd think
> about subclassing off of std::list (although that could have some
> 'interesting' consequences). Failing that, if auto_ptr isn't quite right
> for you, I'd try writing your own auto_ptr variant. The very, very last
> thing I would do is reference counting, unless your project has some
> important other need for it.
>
Anonymous
June 22, 2005 5:32:34 AM

Archived from groups: rec.games.roguelike.development (More info?)

Jim Strathmeyer wrote:

> Smart pointers/reference counting leads to lazy and bad programming.

Agreed. If you're going to use garbage collection, use
real garbage collection. Refcounting misses stuff.

Bear
Anonymous
June 22, 2005 11:55:24 AM

Archived from groups: rec.games.roguelike.development (More info?)

John wrote:
> In my not so humble opinion, writing your own container class in the year
> 2005 for any purpose other than as an intellectual exercise is a pointless
> use of your time and a source of bugs and frustration you don't need.

I'm willing to agree with that:)  I wrote my own system to handle
objects with linked lists. It took huge amount of work and it's
still a bit buggy. I don't use pointers though, just id's of an
array... My container system is very simple. Each object has
cont_id variable which is -1 if the object doesn't contain
anything, or some id which points to the first object in the
container's list of items (objects itself have prev_id and next_id,
I don't have a separate list class for them.)
The level also has a "container" id for each object type, if you
think it that way. I'm calling them "anchors" for the object list.
Anonymous
June 22, 2005 3:42:34 PM

Archived from groups: rec.games.roguelike.development (More info?)

"John" <wBGnkPLN@mailinator.com> wrote in message
news:slrndbgbgm.2p16.wBGnkPLN@mailinator.com...
> On Jim Strathmeyer <strathWHATEVERIGETENOUGHSPAMANYWAYS@ipass.net>
> wrote:
>> Smart pointers/reference counting leads to lazy and bad programming.
>
> Wow. That statement is just stupid. I hope you aren't a professional
> programmer and if you are I hope I never use anything you write.

Regardless of how stupid you think it is, it has nothing on what you
just wrote above.

I can understand Jim's point of view. I don't like smart pointers in
C++ either. I prefer to manage my own memory. If it gets a little
hairy on the MM side of things, then I've probably made some bad design
decisions (which would cause problems later anyway). Code giving you MM
woes is like your body giving you headaches: you can take a pill (or
use smartptr) to treat the symptom, but it might lead to something much
worse. Like poorly designed applications.

Which is why your statement about his programming ability (as
unfounded and baseless as it may be) is rather contradictory. Jim's
statement informs us he has stringent MM guidelines. Ah well...

--
Glen
L:p yt E+++ T-- R+ P+++ D+ G+ F:*band !RL RLA-
W:AF Q+++ AI++ GFX++ SFX-- RN++++ PO--- !Hp Re-- S+
!