Reference counting and API (const reference vs pointer oriented)
Hi there
I have implemented a very simple smartpointer class (invasive
design). And I was wondering what should be the natural API when using
those in a Container.
I choose to define the following operator in my smartpointer class:
....
operator ObjectType * () const
{ return Pointer; }
....
which in turn forces me to have a pointer interface (instead of const
reference):
class Container {
public:
Container():Instance(0) {}
void Set(Object *o) { Instance = o; } // Pointer interface
private:
SmartPointer<Object> Instance;
};
I would have preferred a const reference interface, such as:
class Container {
public:
Container():Instance(0) {}
void Set(Object const &o) { Instance = const_cast<Object*>(&o); }
private:
SmartPointer<Object> Instance;
};
Should I refactor my smartpointer class to be more reference oriented
instead of pointer oriented. I do not see a case where the smart
pointer should point to a NULL pointer.
Comments ?
thanks
-Mathieu
// Full code:
#include <assert.h>
template<class ObjectType>
class SmartPointer
{
public:
SmartPointer():Pointer(0) {}
SmartPointer(const SmartPointer<ObjectType>& p):Pointer(p.Pointer)
{ Register(); }
SmartPointer(ObjectType* p):Pointer(p)
{ Register(); }
~SmartPointer() {
UnRegister();
Pointer = 0;
}
ObjectType *operator -> () const
{ return Pointer; }
operator ObjectType * () const
{ return Pointer; }
void operator = (SmartPointer const &r)
{ return operator = (r.GetPointer()); }
void operator = (ObjectType *r)
{
if(Pointer) Pointer->UnRegister();
Pointer = r;
if(Pointer) Pointer->Register();
}
private:
void Register() { if(Pointer) Pointer->Register(); }
void UnRegister() { if(Pointer) Pointer->UnRegister(); }
ObjectType* Pointer;
};
class Object
{
public:
Object():ReferenceCount(0) {}
virtual ~Object() { assert(ReferenceCount == 0); }
void Register() {
ReferenceCount++;
}
void UnRegister() {
ReferenceCount--;
if(!ReferenceCount) delete this;
}
private:
long ReferenceCount;
};
class Foo : public Object
{
public:
int F;
};
class Container {
public:
Container():Instance(0) {}
void Set(Object *o) { Instance = o; }
private:
SmartPointer<Object> Instance;
};
int main()
{
SmartPointer<Foo> o = new Foo;
Container c;
c.Set( o );
return 0;
}