Sign in to follow this  
Endar

Memory managed base class

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Make a IMBase's destructor virtual and the correct destructors will automatically be called when you delete a pointer to the base class.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this