How do I destruct data associated with an object after the object no longer exists?

Posted by Phineas on Stack Overflow See other posts from Stack Overflow or by Phineas
Published on 2009-07-07T23:34:37Z Indexed on 2010/04/09 19:33 UTC
Read the original article Hit count: 294

Filed under:
|
|

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).

© Stack Overflow or respective owner

Related posts about opengl

Related posts about c++