Chapter 14. Singleton objects

x::singleton implements support for classes that always have only a single class instance during the application's lifetime:

#include <x/singleton.H>

class myClassObj : virtual public x::obj {

// class definition

};

typedef x::ref<myClassObj> myClass;

x::singleton<myClassObj> myClassInstance;

// ...

myClass c(myClassInstance.get());

c->method();

The object gets constructed the first time get() gets invoked. Subsequent calls to get() returns a reference to the same object.

The parameter to the template class must be a reference-counted object that has a default constructor. An instance of the singleton template class can only be declared in the static scope, and may not be declared on the stack.

Note

get() may not be invoked from constructors or destructors of other classes. Constructors and destructors can get called when a thread or an application is in the middle of initializing or terminating, and the underlying support for singleton objects is not available.

An x::singletonptr also implements a singleton object, but with a slightly different lifetime scope.

class global_dataObj : virtual public x::obj {

	// ...
};

typedef singletonptr<global_dataObj> global_data_t;

int main()
{
    global_data_t global_data{x::ref<global_dataObj>::create()};

    // ...
}

// ...

if (foo())
{
    global_data_t global_data;

    global_data->method();
}

An x::singleton object always gets declared in static or application-global scope, and its first get() constructs an object that persists for the duration of the application. The object gets destroyed during the global destruction phase. An x::singletonptr object always gets created in automatic scope, on the stack. The x::singletonptr itself is a subclass of an x::ptr, and gets used like one.

After an x::singletonptr gets constructed in automatic scope with an explicit object, until that instance goes out of scope and gets destroyed, all additional default-constructed instances of the x::singletonptr end up referencing the same object.

A default-constructed x::singletonptr gets constructed as a null x::ptr when no other instance of an explicitly-constructed x::singletonptr exists.

This is the intended design pattern for x::singletonptrs: