Memory managed base class

Started by
2 comments, last by SirLuthor 18 years, 7 months ago
I'm using this class as a base class for most other things in my engine:

#ifndef _IMBASE_H_
#define _IMBASE_H_

#include "list.h"

/**
 * Provides the basic menmory managment for objects.
 */
class IMBase
{
private:

	static util::list<IMBase*> activeList;		///< The list of active objects (with ref_count > 0)
	static util::list<IMBase*> deadList;		///< The list of dead objects (with ref_count == 0)

	long ref_count;			///< Reference variable

public:

	/**
	 * Default constructor
	 * Sets ref variable to 1
	 */
	IMBase()
		:	ref_count(1)
	{
		activeList.push_back(this);	// add this object to the live list
	}

	/**
	 * Called by when a function or an object is using this object.
	 */
	void get()
	{
		ref_count++;	// add another thing using this object
	}

	/**
	 * Called by a function or an object when it is finished using this object.
	 */
	void drop()
	{
		ref_count--;	// an object is done using this object

		if( ref_count <= 0 )
			IMBase::makeDead(this);
	}

	/**
	 * Search for the passed pointer in the activeList and if found, delete
	 * it from the list, and insert it into the deadList.
	 * \param p A pointer of type IMBase*, which is the pointer to delete from activeList
	 * and insert into the deadList.
	 */
	static void makeDead(IMBase* p)
	{
		util::list<IMBase*>::iterator i = activeList.begin();
		for( ; i != activeList.end(); i++ )
			if( (*i) == p ){
				activeList.erase(i);// delete element i from the active list
				deadList.push_back(p);
			}
	}

	/**
	 * Deletes all the items in the deadList from memory.
	 */
	static void collectGarbage()
	{
		util::list<IMBase*>::iterator i = deadList.begin();
		for( ; i != deadList.end(); i++ )
			delete (*i);

	}

	/**
	 * Delete all the items in the deadList and activeList.
	 */
	static void collectAllGarbage()
	{
		collectGarbage();	// delete all in deadList

		// delete all items in the activeList
		util::list<IMBase*>::iterator i = activeList.begin();
		for( ; i != activeList.end(); i++ )
			delete *i;

	}

};

#endif


One thing that I forgot is that when I'm finished with an object and call object->drop() and it is added to the dead list, once I call collectGarbage, then, that object is done for, and its destructor doens't get called, because 'delete' is being called from an IMBase pointer, and not the original object pointer. How do I fix this? Should I scrap this method of memory management and find a better one?
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Advertisement
Make a IMBase's destructor virtual and the correct destructors will automatically be called when you delete a pointer to the base class.
<smack the side of my head> DUH!

Thanks Rebooted.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
As Rebooted said, you need a virtual destructor. I would go so far as to say that in an class that has any virtual methods at all, you should always make the destructor virtual as well. Just a good rule in general, unless you specifically need it to be non-virtual, and to tell you the truth, I can't think of any time when that would be the case.
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!

This topic is closed to new replies.

Advertisement