To implement reference counting we use an IUnknown
-like interface and a smart pointer template class. The interface has implementation for all the reference-count methods, including Release()
:
void IUnknownLike::Release()
{
if( --refCount == 0 ) {
delete this;
}
}
The smart pointer template class has a copy constructor and an assignment operator both accepting raw pointers. So users can do the following:
class Class : public IUnknownLike {
};
void someFunction( CSmartPointer<Class> object ); //whatever function
Class object;
someFunction( &object );
and the program runs into undefined behavior - the object is created with reference count zero, the smart pointer is constructed and bumps it to one, then the function returns, smart pointer is destroyed, calls Release()
which leads to delete
of a stack-allocated variable.
Users can as well do the following:
struct COuter {
//whatever else;
Class inner;// IUnknownLike descendant
};
COuter object;
somefunction( &object.Inner );
and again an object not created with new
is delete
d. Undefined behavior at its best.
Is there any way to change the IUnknownLike
interface so that the user is forced to use new
for creating all objects derived from IUnknownLike
- both directly derived and indirectly derived (with classes in between the most derived and the base)?