Topic: Q: list<A*>::erase


Author: Eyal Ben-David <eyal.ben-david@aks.com>
Date: 1998/06/17
Raw View
Marc Ferry wrote:
>
> I am getting confused about the erase() method of a list.
> I would like to remove (and delete) the first element of
> a list containing pointers. Among the following methods,
> which one do you suggest ?
>

[...]

>
> Thanks for your help.
> Marc

Hello,

I prefer to write a special class for pointers. The owning
semantics is enables/disabled by a template parameter as
in tha following example:

#include <list>

template <class T, int Owns = 1>
class PtrList : public std::list<T*>
{
public:
   // write constructors for your needs
   //
   PtrList() {}

   // Special erase that delete the pointer.
   //
   void erase_and_delete( iterator i )
   {
      if (Owns) delete *i;
      erase(i);
   }

   // destructor
   //
   ~PtrList()
   {
      if ( Owns )
         while ( !empty() )
            erase_and_delete( begin() );
   }
};


BTW what are the consequences of renaming 'erase_and_delete' to 'erase'
?
I didn't do so since I suspect that the base class erase will be called
instead of the one I supply ( but this problem might happen with the
destructor anyway ).

Maybe the better solution is to use list<T*> as a private member
instead of derivation ( with re-implementing all list-interface ) ?

Eyal
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: AllanW@my-dejanews.com
Date: 1998/06/17
Raw View
In article <35867306.F1A70DF6@netmansys.fr>,
  Marc Ferry <marc@netmansys.fr> wrote:
>
> I am getting confused about the erase() method of a list.
> I would like to remove (and delete) the first element of
> a list containing pointers. Among the following methods,
> which one do you suggest ?
[Snip]
> void X::removeAndDeleteFirst(list<A*>& a_ptr_list)
> {
>   list<A*>::iterator it = a_ptr_list.begin();
>   A *a = *it;
>   a_ptr_list.erase(it);
>   delete a;
> }
Based on what you're implying, this is the correct method.  The list
contains A pointers, presumably added with
    a_ptr_list.add(new A);
If that's the case, then you must delete the A when you remove it from
the list.  Remember that an iterator is not an A pointer; conceptually
it is a pointer to an A pointer, except that the iterator can only point
inside the list.

> In other words, does the call to erase() also remove the
> pointed object, or should a delete be called on the pointed
> object ? In the second case, when should it be done (after
> or before the call to erase()) ?
The call to erase() removes the object that is in the list.  In this case,
that's the A-pointers.  You need to use the A-pointer to delete the A
first.  The last version of your function does that.

So long as you use a list of A* for your array, you must be certain to
always delete the pointed-to A whenever you remove a pointer from the
list, and you must always remember to remove all the pointers in the
list (and delete the pointed-to A elements) whenever the list itself
is being destroyed.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]