It would be nice to extend ScopedPointer to include a policy object:
template <class ObjectType, class PolicyType = DefaultScopedPointerPolicy <ObjectType> >
class ScopedPointer
{
//...
Now we define the default policy:
template <class ObjectType>
struct DefaultScopedPointerPolicy
{
void destroy (ObjectType* object) { delete object; }
void assign (ObjectType* object) { }
void release (ObjectType* object) { }
};
At this point, ReferenceCountedObjectPtr can reuse most of the code:
template <class ReferenceCountedObjectClass>
class ReferenceCountedObjectPtr : public ScopedPointer <ReferenceCountedObjectClass,
ReferenceCountedObjectPolicy <ReferenceCountedObjectClass> >
{
public:
//...
};
Implementing the policy object for ReferenceCountedObjectPtr is easy:
template <class ReferenceCountedObjectClass>
struct DefaultScopedPointerPolicy
{
void destroy (ReferenceCountedObjectClass* object) { releaseObject (); }
void assign (ReferenceCountedObjectClass* object) { object->incrementReferenceCount (); }
void release (ReferenceCountedObjectClass* object) { object->decrementReferenceCount (); }
};
The only thing left to do is rewrite ScopedPointer member functions to use the policy instead of the old hard coded behavior. Here’s an example:
before
ScopedPointer& operator= (ObjectType* const newObjectToTakePossessionOf)
{
if (object != newObjectToTakePossessionOf)
{
ObjectType* const oldObject = object;
object = newObjectToTakePossessionOf;
delete oldObject;
}
return *this;
}
after
ScopedPointer& operator= (ObjectType* const newObjectToTakePossessionOf)
{
if (object != newObjectToTakePossessionOf)
{
ObjectType* const oldObject = object;
object = newObjectToTakePossessionOf;
PolicyType::assign (object);
PolicyType::release (oldObject);
}
return *this;
}
Now we can delete most of the code in ReferenceCountedObjectPtr. Less code, and way more complicated!
But then someone could implement their own custom policy. For example, when the underlying object exists in an external DLL and we can’t just call operator delete (because there are two instances of the C Runtime heaps). This would make ScopedPointer more broad.