Specifying a custom base

The following example uses a create() method to instantiate a new reference-counted object, with its initial pointer or reference:

typedef x::ref<buttonObj> button;

button b(button::create());

// ...

b->click();

x::ref's and x::ptr's base typedef actually comes from an optional second parameter to the x::ref and the x::ptr template class, which defaults to x::ptrrefbase. This can be overridden:

class buttonBase;
class buttonObj;

typedef x::ref<buttonObj, buttonBase> button;
typedef x::ptr<buttonObj, buttonBase> buttonptr;

class buttonBase {

public:

    template<typename ptrrefType> class objfactory {
    public:

        static ptrrefType create()
        {
            // ...
        }
    };
    static const int default_width=50, default_height=50;
};

An x::ref or an x::ptr's create() method invokes base::objfactory<T>::create(), where T is either the x::ref or the x::ptr type. in this example, button::base gets typedef-ed to buttonBase instead of x::ptrrefBase, so invoking button::create() invokes the custom create() method that returns an x::ref or an x::ptr, with button::base::default_width and button::base::default_height referencing the given definitions. In this manner, it's possible to define custom create() methods that construct new pointers or references in arbitrary ways, rather than just by invoking the corresponding object constructor.

The above example also gives the general naming convention: nameObj for the reference-counted object itself; name for the reference to the object, and nameptr for the nullable reference pointer to the object, with the same class typedef-ed to name::base and nameptr::base .

Sometimes it's convenient to keep the default variadic create(), and just supplement base with other stuff. Use the following design pattern to inherit the the default variadic implementation of create() into the base class:

class buttonBase;
class buttonObj;

typedef x::ref<buttonObj, buttonBase> button;
typedef x::ptr<buttonObj, buttonBase> buttonptr;

class buttonBase : public x::ptrrefBase {

public:
    static const int default_width=50, default_height=50;
};

Here, buttonBase subclasses x::ptrrefBase, which is the default base of an x::ref or an x::ptr, and inherits the default implementation of objfactory. For completeness, here's the actual definition of x::ptrrefBase:

class ptrrefBase {
public:

    template<typename ptrrefType> class objfactory {
    public:

        template<typename... Args_t>
        static inline ptrrefType
        create(Args_t &&...args)
        {
            return ptrrefType(new typename ptrrefType
                      ::obj_type(std::forward<Args_t>(args)...));
        }
    };
};

x::ref and x::ptr also define the obj_type member typedef to the reference-counted object type. x::ref::create() and x::ptr::create() forward their arguments to base::objfactory<T>::create(), where T is the x::ref or the x::ptr type.