Inheritance from STL container

This is a discussion on Inheritance from STL container within the C++ Programming forums, part of the General Programming Boards category; Hi, I have a problem with 'slicing' when deleting an object allocated on the heap using a base class pointer. ...

  1. #1
    Registered User SpaceCadet's Avatar
    Join Date
    Oct 2006
    Posts
    23

    Question Inheritance from STL container

    Hi,

    I have a problem with 'slicing' when deleting an object allocated on the heap using a base class pointer. The base class is a std:list. Because the std::list does not have a virtual destructor, the derived class object will be sliced and therefore leak if I delete it with a std::list *ptr.

    I appreciate this sounds a little wierd, but this requirement comes from dependencies within a legacy code base. This application runs on Solaris.

    I feel sure the solution must be straight forward enough, but I just can't identify it right now.

    Help much appreciated..

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,144
    Do not inherit from standard containers, they simply were not designed to be base classes (hence the lack of a virtual destructor).
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    What is your derived class trying to achieve? You could always encapsulate the stl::list

  4. #4
    Registered User SpaceCadet's Avatar
    Join Date
    Oct 2006
    Posts
    23

    Bit of background

    I am working on piece of software written by a third party vendor. The third party has completely misunderstood the STL.

    They have written a custom template wrapper object to contain a pointer of type T. A further custom list container which encapsulates a std::list states in the comment the incorrect conclusion that the std::list may not contain pointers. (Rubbish!)

    Therefore the custom list container, contains the custom wrapper object that in turn contains the pointer to type T that could have gone straight into the std::list.

    I am trying to replace the custom container with a new implementation that inherits from std::list. The intent is to open up the capability for clients of the custom container to use the std::list methods directly in order to manage the 'new' custom list container.

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,053
    Just a thought: Instead of deriving your class form std::list, you could override the & opperator to return a list pointer. Then you would need to implement all of the meathods of list yourself (perhalps by including a list object that the meathods would be forwarded to). Simmilarly you could override opperator& to return a spcial object that can be cast to a list pointer, but by itself also has aditional functionallity, such as calling meathods that are not part of std::list.
    Last edited by King Mir; 10-11-2006 at 11:00 AM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,144
    Is there any reason to have a custom list container in the first place? Why not just have the wrapper object use a std::list? Or if you really need to, write a wrapper for std::list to replace the current custom list container.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User SpaceCadet's Avatar
    Join Date
    Oct 2006
    Posts
    23
    By using a wrapper, clients of that wrapper can not use the std::list API directly to manage data held within the Wrapper::std::list mList member variable.

    The ambition of this exercise is to deprecate the custom template wrapper class and replace the custom list container with a new implementation that can be manipulated using the std::list API.

    Hmmm. Your point that the lack of a virtual destructor within std::list did occur.

    I am starting to think that a wrapper that implements the std::list API functions, where the wrapper implementation calls the std::list implementation via the Wrapper::std::list mList member variable might be the best way around this issue...

    Thanks.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,144
    I am starting to think that a wrapper that implements the std::list API functions, where the wrapper implementation calls the std::list implementation via the Wrapper::std::list mList member variable might be the best way around this issue...
    Yes, that is what I had in mind, given your restrictions.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    Another option is private inheritance, which avoids the non-virtual destructor issue and makes exposing the list class easier by allowing you to do things like:
    Code:
    class custom_list : private std::list
    {
    public:
      using std::list::size;
      using std::list::empty;
      // etc.
    };
    Another option is to not create a custom list class at all. If you deprecate the third party custom container and replace it with your own custom list, then the current users will have to change their code anyway. You could just allow them to use the actual standard library containers, and add functionality through non-member functions (similar to the standard algorithms). This has the added benefit of allowing flexibility as far as which container to use. Depending on your scenario, it is possible that a vector or deque might be more appropriate than a list, and well written non-member functions will be able to handle any of those.

    If you do write your own class, consider making the underlying container a template type that defaults to std::list to provide that flexibility. I don't know your requirements, so maybe a list will always be the right choice, but it is something to think about.
    Last edited by Daved; 10-12-2006 at 10:07 AM.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Does the template wrapper in the legacy code delete objects on destruction?

    You may want to use Boost.Ptr_Container instead of writing your own solution.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User SpaceCadet's Avatar
    Join Date
    Oct 2006
    Posts
    23
    A fine suggestion.

    Unfortunately the legacy code must be built using a compiler version recognised and support by it's owners. The version of the Sun C++ compiler, they support does not build the Boost libraries. This is a contractual matter, not an engineering one.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stl container to store more than 1 type
    By sujeet1 in forum C++ Programming
    Replies: 7
    Last Post: 05-09-2007, 05:10 AM
  2. inherited classes and stl container
    By rahulsk1947 in forum C++ Programming
    Replies: 9
    Last Post: 05-05-2007, 03:27 PM
  3. Linked List Queue Implementation help
    By Kenogu Labz in forum C++ Programming
    Replies: 8
    Last Post: 09-21-2005, 11:14 AM
  4. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-24-2004, 12:22 AM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 04:49 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21