CPtrList cleanup options.

I use many CPtrList instances in my app, and for each one, I do something like this to cleanup:

if (m_pThings)
{
  while (!m_pThings->IsEmpty())
  {
  CThing* pThing = (CThing*)m_pThings->RemoveHead();

  if (CThing)
    delete pThing;
  }

  delete m_pThings;
  m_pThingS = NULL;      
}



I don't like writing the same thing over and over again, the only difference being the type of object contained.

Is there a way to write that code as a global utility funciton like : CleanupList(CPtrList* a_pList) or something to which I can simply pass the pointer to the CPtrList and cleanup as necessary w/o knowing the type of object? Or do I have to look at re-writing code using the CTypedPtrList that I recently became aware of?

thanks!
-Paul

PMH4514Asked:
Who is Participating?
 
AlexFMConnect With a Mentor Commented:
You can write template function:

template <class T>
void DeleteCPtrList(CPtrList* p)
{
  if (p)
  {
    while (!p->IsEmpty())
    {
      T* pT = (T*)p->RemoveHead();

      if (pT)
         delete pT;
    }

    delete p;
}
0
 
AxterCommented:
Why not create your own derived class of CPtrList, and have your derived class destrcutor delete the objects.
0
 
PMH4514Author Commented:
>>Why not create your own derived class of CPtrList, and have your derived class destrcutor >>delete the objects

umm.. that would be too easy wouldn't it?  ;-)

seriously though, how would that make a difference? Even if I did that, the CMyPtrList would need to know what type of objects it was holding.

I mean, this isn't possible is it:

if (m_pThings)
{
  while (!m_pThings->IsEmpty())
  {
  pThing = m_pThings->RemoveHead();

  if (pThing)
    delete pThing;
  }

  delete m_pThings;
  m_pThingS = NULL;    
}


because I need to specify a class type to declare pThing

0
[Webinar] Improve your customer journey

A positive customer journey is important in attracting and retaining business. To improve this experience, you can use Google Maps APIs to increase checkout conversions, boost user engagement, and optimize order fulfillment. Learn how in this webinar presented by Dito.

 
PMH4514Author Commented:
ahsooo.. once again the ellusive Template rears it's head.. I keep seeing those in use, but haven't taken any time to study them.  So could you illustrate an example of how I would utilize something like that, in a situation where I currently have pointer to a CPtrList as a member variable? Do I have to change the type of all those existing member variables, or just create an instance of this template class and pass my existing CPtrList pointer to it for cleanup?
0
 
AxterCommented:
>>seriously though, how would that make a difference?

If all the objects on your list are derived from the same base class, then all you have to do is cast it to the base class, and call delete on it.

That is providing that your base class has a virtual distructor.
0
 
AxterCommented:
FYI:
I would recommend against using CPtrList in general, and would recommend using a container of base class pointers instead.
It would be much safer.

0
 
PMH4514Author Commented:
>>If all the objects on your list are derived from the same base class, then all you have to do is cast it to the base class, and call delete on it.

All the objects on any given list are of the same type, which is why I can put code as described in my first post, within each class destructor that is using a CPtrList to maintain a collection of objects.     But there are CPtrList lists throughout the system in non-related classes, and while each contains objects of the same type, the type of object is different amount distinct CPtrList instances.  I mean I could do the Java like thing and create a CObject with a virtual destructor and derive every class in my system from CObject but that seems a bit much.
0
 
PMH4514Author Commented:
>>I would recommend against using CPtrList in general, and would recommend using a container of base class pointers instead.
>>It would be much safer.

I'm getting the impression that CPtrList is generally "not well regarded" from your comments and others I've read, but I must admit I still don't understand what the drawback to using them is, even yes, for maintaining a collection of base class pointers.

0
 
AlexFMCommented:
CPtrList* pList = new CPtrList();
// fill pList with CThing* instances

// clear list
DeleteCPtrList<CThing>(pList);
pList = NULL;
0
 
AxterConnect With a Mentor Commented:
>>but I must admit I still don't understand what the drawback to using them is

The draw back is that it's not type safe.

When you have a type safe container, if you make a mistake, and try to add the wrong type on it, you'll find out at compile time.

With containers that are not type safe, you find out (if you're lucky) at runtime.
Moreover, you might find out at runtime when the customer is using it, instead of when it's in the development stage.

It's very easy to copy and past the wrong variable, and if you put the wrong variable on a container that takes a void pointer, the compiler is not going to complain about it.
With a type safe container, you find out right away that you made a mistake.
0
 
PMH4514Author Commented:
Thanks Alex - Templates look pretty cool. I'm going to read up on them.

Axter:
>>The draw back is that it's not type safe.

Good enough.. I thought it was for performance reasons.
0
 
PMH4514Author Commented:
... just taking a look at some of the template stuff on MSDN.. weird, it's kinda a different way of thinking about things.  Probably one of those things you have to get used to huh?
0
 
AxterCommented:
>>Probably one of those things you have to get used to huh?

I wouldn't use the MSDN stuff for template learning.

IMHO, MFC's template containers are terrible.

I would start out with std::vector.
It's a good all around generic container, that comes in very handy.

Once you get use to it, you can pick up the other STL containers fairly easy.

Unlike MFC's containers, the stl containers have a pretty consistant interface.
0
 
PMH4514Author Commented:
ok thanks
0
All Courses

From novice to tech pro — start learning today.