Instead of defining your singleton explicitly by hiding the constructors and having the get method what
you can do is you can rely on an inversion of control container used in a typical Dependency Injection
framework to basically make a singleton for you because what happens in the containers is you allow
yourself to configure different components with different lifetimes and Singleton is nothing more than
a specification of a lifetime specifically requires that only one component exist at any one point in
time.
So let me show you the absolute minimal example of how you would use a dependency injection framework.
And in this case I'm using boost the I by the way here is the entire source code here and I want to
show you how you can use it to actually define a component to have a singleton lifetime and how we can
verify that it is in fact a singleton.
So let's suppose that I'm going to have an interface called foo which is going to have just a single
method called name which is going to return a string.
Now what I'm going to do is have a concrete implementation of foo like cells.
I'm going to just implement the name here.
And in addition I'm just going to have an idea so that we can track the fact that this component is
in fact being created only once all have static ID here all incremented in the constructor.
So in the constructor would do plus plus ID and some are down below I will initialize it to zero initialize
it to zero.
Here for example and then for the implementation of name I'm actually going to print both the name which
I'll call this one food and I'll also append the ID so we get to see that both of the components that
we create subsequently have actually the same ID.
So here are just lexical cast to a string the ID value.
All right that's it.
So what we can do now is we can start using this component in yet another component so let's suppose
we have a structure called Bar which needs a singleton instance of foo.
So here we have a shared tr of foo foo and we want a singleton instance of food to be injected here
and we're going to be using the bus.
The framework for this.
So let's go ahead and configure the container first of all this is done using an injector so auto injector
equals the I make injector.
And here is where you specify a set of policies for how the components are actually created.
So what we want to state is we want to state that whenever somebody asks for an instance of food as
if we're going to be required to do here because here the bar has a dependency on food shared pointers
so we're going to need to provide an instance whenever somebody asks for an I food.
What we're going to do is we're going to map it to food.
So we're going to provide an instance of food however by default this is going to construct a new instance
so what we want instead is we want to Singleton and this is also possible in this the I continue or
you simply say Dauth in and you specify the lifetime.
In this case it's going to be a singleton.
So this is all that you need to do to make sure that foo is a singleton whenever it actually gets injected.
And then we can make instances of bar.
So let's have that auto bar one equals injector Dalt create.
And here on the a shared VTR I'm also going to be using shared loss here.
So I need the shirt of bar here and I'll replicate this and I'll make yet another instance just to prove
to you that we are working with that same instance.
So we can try printing the names of both of the instances of the foo member just to see that they are
identical because remember we have this idea which gets incremented.
So if somebody calls the constructor twice the idea is going to be different in different instances
and we expect the idea to be equal to one because it starts with zero and we only expect to increment
it once so we get to see a 1 in both of these cases.
So let's actually verify that first of all.
So I'm going to say bar one foo name here and I'll replicate this once again and varify bar to as well.
But we can also just compare the pointers because remember this is a shared pointer in both of these
cases and we can just compare the pointers and see whether they point to the same object.
So here I'll have bool Alpha.
Just so that we get to outputs the the comparison nicely.
Instead of having a 0 or a 1 we're going to get a true or a false.
And here I can take bar one foo and just use a get on the shared pointer and compare it with bar to
foo and foo.
By the way yes that's correct.
With a get here.
So we're expecting a true here because they are a singleton they all refer to the same instance so let's
actually compile all of this.
And I don't know what this is all about this actually compile and see what's going on here.
So hopefully we get identical printouts and also get the get everything else correctly done.
OK and here is the output.
So for both of these we get food one which means that we only incremented the static variable once we
get a value of true when we compare the value of the shared pointers.
So as you can see this is an alternative to having your own singletons you simply use a dependency injection
framework and this way you can just configure the lifetime of a component to be a singleton and then
the rest of it is taking care for you.