I'm creating a class (say, C) that associates data (say, D) with an object (say, O). When O is destructed, O will notify C that it soon will no longer exist :( ... Later, when C feels it is the right time, C will let go of what belonged to O, namely D.
If D can be any type of object, what's the best way for C to be able to execute "delete D;"? And what if D is an array of objects?
My solution is to have D derive from a base class that C has knowledge of. When the time comes, C calls delete on a pointer to the base class.
I've also considered storing void pointers and calling delete, but I found out that's undefined behavior and doesn't call D's destructor. I considered that templates could be a novel solution, but I couldn't work that idea out.
Here's what I have so far for C, minus some details:
// This class is C in the above description. There may be many instances of C.
class Context
{
public:
// D will inherit from this class
class Data
{
public:
virtual ~Data() {}
};
Context();
~Context();
// Associates an owner (O) with its data (D)
void add(const void* owner, Data* data);
// O calls this when he knows its the end (O's destructor).
// All instances of C are now aware that O is gone and its time to get rid
// of all associated instances of D.
static void purge (const void* owner);
// This is called periodically in the application. It checks whether
// O has called purge, and calls "delete D;"
void refresh();
// Side note: sometimes O needs access to D
Data *get (const void *owner);
private:
// Used for mapping owners (O) to data (D)
std::map _data;
};
// Here's an example of O
class Mesh
{
public:
~Mesh()
{
Context::purge(this);
}
void init(Context& c) const
{
Data* data = new Data;
// GL initialization here
c.add(this, new Data);
}
void render(Context& c) const
{
Data* data = c.get(this);
}
private:
// And here's an example of D
struct Data : public Context::Data
{
~Data()
{
glDeleteBuffers(1, &vbo);
glDeleteTextures(1, &texture);
}
GLint vbo;
GLint texture;
};
};
P.S. If you're familiar with computer graphics and VR, I'm creating a class that separates an object's per-context data (e.g. OpenGL VBO IDs) from its per-application data (e.g. an array of vertices) and frees the per-context data at the appropriate time (when the matching rendering context is current).