About putting different types of objects on std::list

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>::push_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
22 answers Last reply
More about about putting types objects list
  1. 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)
  2. 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)
  3. 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
    :-).
  4. 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
  5. 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.
  6. 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.
  7. 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)
  8. 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
  9. 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 :/
  10. 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 :)
  11. 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...
  12. 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
  13. 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)
  14. 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
  15. 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>::push_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
  16. 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.
  17. 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)
  18. 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.
  19. 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>::push_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.
    >
  20. 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
  21. 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.
  22. 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:Pyt E+++ T-- R+ P+++ D+ G+ F:*band !RL RLA-
    W:AF Q+++ AI++ GFX++ SFX-- RN++++ PO--- !Hp Re-- S+
Ask a new question

Read More

Development Video Games