In sfntly C++ port, an object ref-counting and smart pointer mechanism is implemented. The implementation works very much like COM.
Ref-countable object type inherits from RefCounted<>, which have addRef() and release() just like IUnknown in COM (but no QueryInterface). Ptr<> is a smart pointer class like CComPtr<> which is used to hold the ref-countable objects so that the object ref count is handled correctly.
Lets take a look at the example:
class Foo : public RefCounted<Foo> { public: static Foo* CreateInstance() { Ptr<Foo> obj = new Foo(); // ref count = 1 return obj.detach(); // Giving away the control of this instance. } }; typedef Ptr<Foo> FooPtr; // Common short-hand notation. FooPtr obj; obj.attach(Foo::CreateInstance()); // ref count = 1 // Take over control but not bumping // ref count. { FooPtr obj2 = obj; // ref count = 2 // Assignment bumps up ref count. } // ref count = 1 // obj2 out of scope, decrements ref count obj.release(); // ref count = 0, object destroyed
In this case the smart pointer is pretty dumb and dont count on it to nicely destroy your objects as designed. Try refactor your code like
class I; // the common interface and implementations class A : public I, public RefCounted<A>; // A specific implementation class B : public I, public RefCounted<B>; // B specific implementation
If you are not passing that object back, you are the end of scope.
Be very careful when using the assignment operator as opposed to attaching. This can easily cause memory leaks. Have a look at The difference between assignment and attachment with ATL smart pointers. Since were using essentially the same model, it applies in pretty much the same way. The easiest way of knowing when to Attach and when to assign is to check the declaration of the function you are using.
// Attach to the pointer returned by GetInstance static CALLER_ATTACH FontFactory* GetInstance(); // Assign pointer returned by NewCMapBuilder CMap::Builder* NewCMapBuilder(const CMapId& cmap_id, ReadableFontData* data);
The implementation of COM-like ref-counting and smart pointer remedies the lack of garbage collector in C++ to certain extent, however, it also introduces other problems. The most common one is memory leakage. How do we know that our code leak memory or not?
ENABLE_OBJECT_COUNTER
and REF_COUNT_DEBUGGING
. All ref-count related activity will be ouput to stderr.Use your favorite editor to transform them into SQL statements, e.g. Regex pattern
^([ACDR]) class RefCounted<class sfntly::([A-Za-z0-9:]+)>[ *const]+:oc=([-0-9]+),oid=([0-9]+),rc=([-0-9]+)
Replace to
insert into log values(\1, \2, \3, \4, \5);