Using singleton objects

itemlayoutmanager.C gives an example of a design pattern that uses LibCXX's x::singletonptrs in ways that are compatible with LibCXX Widget Toolkit's rules for reference-counted objects and their references.

class appObj : virtual public x::obj {

public:

// ...
};

typedef x::singletonptr<appObj> app;

// ..............

auto main_window=x::w::main_window::create(
    []
    (const auto &main_window)
    {
        // ...

    });

app my_app{x::ref<appObj>::create(main_window)};

The appObj class contains references to key widgets and other application data, such as:

itemlayoutmanager.C stores the list of discrete pizza toppings in its application object.

The appObj object and the constructed x::singletonptr get constructed in automatic scope. Because they get constructed in automatic scope, both of the object and the x::singletonptr get destroyed before the main itemlayoutmanager() function returns. itemlayoutmanager() waits for the application window's Close button, that closes and terminates the application.

All the references to this object go out of scope and get destroyed in the right order. Then, elsewhere in the application code:

app my_app;

if (!my_app)
   return;

my_app->method();

This default-constructed x::singletonptr gets declared anywhere in the application code, also in automatic scope, anywhere where it's convenient to do so. The constructed x::singletonptr references the same object that's already constructed.

This basic approach involes constructing the singleton object (appObj in this case) in main() or some other high level function that does not terminate until the entire application gets terminated. The singleton object's x::singletonptr does not exists in global or static scope, but in automatic scope of this function that returns only when the entire application terminates.

Elsewhere in the application, as needed, the same x::singletonptr gets constructed, also in automatic scope, and this instance ends up referencing the same object that already exists in the high level function's automatic scope (provided that the high level function hasn't terminated and destroying its automatically-scoped objects).

In this manner, all references to the singleton object exist in automatic scope, and get automatically cleaned up when execution leaves the scope; but the application data behaves as a global singleton, conveniently accessible anywhere in the application.

See Chapter 30, Print Dialog for another example of using singleton pointer objects.