I have a struct like this one:
struct foo
{
IBar* ptr;
};
which is part of a foo object with a long lifetime. Users often get instances of those objects in different callbacks and sometimes they inject stuff into the IBar* in certain places, use it in later callbacks, free it eventually. (IBar has virtual void free() { delete this; } which can be overridden of course).
The problem is I want to transition my users to the possibility of having more than one IBar* per foo struct and I want to make the transition smooth. One idea for making the transition smooth is changing the foo struct as follows:
struct foo
{
foo()
{
ptr = reinterpret_cast<IBar*>(new IBar*[N]);
memset(ptr, 0, sizeof(IBar*)*N);
}
IBar*& getBarPtr(size_t offset)
{
return reinterpret_cast<IBar**>(ptr)[offset];
}
IBar* ptr;
};
My idea is that this way, anyone using the old style where they expect there to be only one IBar* should fallback on using the first of the N transparently in the usual way of using it:
someFoo.ptr = new iImplementIBar(...);
but those users who begin to transition to new usage can get their offset and instead do
someFoo.getBarPtr(myOffset) = new iImplementIBar(...);
the problem, though, is that foo had a reset method which used to do this:
void reset() {
if (ptr)
{
ptr->free();
ptr = 0;
}
}
which this idea replaces with this:
void reset() {
IBar** ptrs = reinterpret_cast<IBar*>(ptr);
for (size_t i = 0; i < N; ++i)
if (ptrs[i])
{
ptrs[i]->free();
ptrs[i] = 0;
}
}
and the functionality of the free in the above seems to be lost. Is there a way to make this work? Or what goes wrong?
If you really must do this without implementing a newer interface, why not have something like this:
That way users of the existing ‘foo’ interface continue to use
ptrbut the newbarsinterface is also available for those who wish to use it.Without knowing more it’s hard to know whether the above design makes sense.