+1  A: 

What you're looking for is Boost::shared_ptr, or some similar smart-pointer system.

Head Geek
A: 

To answer the question, "What if D is an array of objects ?", I'd suggest a vector<>, but you'd have to associate it with D:

struct D_vector
    :D
{
    vector<whatever> vw;
};
keraba
+1  A: 

The question is rather vague on the requirements, so it's hard to give a good concrete answer. I hope the following helps.

If you want the data to disappear immediately when its owner dies, have the owner delete it (and notify C if the C instances need to know). If you want C to do the deletion at its leisure, your solution looks fine. Deriving from Data seems to me the right thing to do. (Of course it is crucial that ~Data() be virtual, as you have done.)

What if D is an array of objects? There are two interpretations of this question. If you mean that D is always an array, let it be an array (or vector<>) of pointers to Data. Then in C::purge() walk the vector and delete the objects. If you mean that D could be an array of objects but could also be a single object, there are two ways to go. Either decide that it is always an array (possibly of size 1), or that it is a single object (derived from Data) which can be a class wrapping the array of the actual objects (or pointers to them). In the latter case, the wrapper class destructor should walk the array and do the deletions. Note that if you want the array (or vector<>) to contains the actual objects, not pointers to them, (in which case you won't have to walk the array and delete manually) then you'll have the following limitations. 1. All objects in the array will have to be of the same actual type. 2. You will have to declare the array to be of that type. This will lose you all the benfits of polymorphism.

Ari