« back to Projects & Downloads
Reference-Counting Template for C++
I made a simple class template that performs automatic reference counting and memory management of C++ objects. If you want to reference count objects of YourClass, simply pass around and store adu::ref<YourClass> instead of YourClass*, and the objects will be automatically deleted when the last reference to them disappears. My primary goal in designing this template was to make it easy and intuitive to use.
Download adu_refcounting v1.0 — released January 18, 2010 under the MIT License — includes source and examples.
Quick outline:
- Namespaces: everything is in the
adunamespace to prevent naming conflicts - No new syntax: member access and dereferencing of
adu::ref<YourClass>is the same as ofYourClass* - Easy to support: all you have to do is inherit from
adu::refcounted_object - Polymorphic conversion: an
adu::ref<SubClass>can be passed where aadu::ref<SuperClass>is expected (but not vise-versa) - Const promotion: a
adu::ref<YourClass>can be passed where aadu::const_ref<YourClass>is expected (but not vise-versa) - Intrinsic casting support:
someReference.dyn_cast<...>()replacesdynamic_cast<...>( somePointer ), and behaves identically
One recommendation I have is to typedef references as inner types to each of your classes. This allows you to use YourClass::Ref instead of adu::ref<YourClass>, which I find much more intuitively readable. This is purely a stylistic suggestion, so it's really up to you. A macro is provided to make the appropriate typedefs, if you choose to use it.
Here is a simple example, to give you a taste of how the code feels (the download contains larger and more verbosely explained examples). A reference-countable class could look something like this:
// Include the appropriate header. #include "adu_refcounting.hpp" // Inherit from the provided base class. You don't have to, but doing this means you don't have to do any extra work. class YourClass : public adu::refcounted_object { public: // Use the macro to define the ref template instantiations as inner types. Aagain, not required, but it's the easist way. adu_standard_reference_typedefs(YourClass); // An example method to be used down below: void mutate() { /* ...(change this object in some way)... */ } };
Then you would use YourClass like this:
void example_function() { // Create an object and store it in a ref instead of a pointer. Just use YourClass::Ref instead of YourClass* YourClass::Ref obj = new YourClass(); // Assuming YourClass has a mutate() method that changes the object in some way, // you call it using the same syntax as if obj were a pointer. obj->mutate(); // Pass obj to some function. This function can accept either a YourClass* or a YourClass::Ref, // or the const versions of either. do_something_with( obj ); // Now assign the object to a const reference. Using YourClass::ConstRef instead of const YourClass* YourClass::ConstRef cannot_modify = obj; // The following commented-out line would not compile, because mutate() is not a const member. // It's the same as trying to call mutate() on a const pointer: illegal. /* cannot_modify->mutate() */ // Assuming do_something_with() accepts a YourClass::ConstRef, this line will work just fine. // YourClass::Ref will auto-convert to a YourClass::ConstRef (utilized above when passing obj), // but YourClass::ConstRef will *not* convert to a YourClass::Ref. Same as pointers. do_something_with( cannot_modify ); // Once 'obj' and 'cannot_modify' go out of scope, the object you new'd at the beginning of the method will be deleted. Voilà! } void do_something_with( YourClass:ConstRef obj ) { /* ...do something with obj (that doesn't modify it, of course)... */ }
The download up above contains more extensive examples, both of the recommended techniques and of what to do if you can't or don't want to do things that way.