The following small example implements a singleton pattern that I\'ve seen many times:
#include
class SingletonTest {
private:
Singleton
You could write a deinitialization function and call atexit()
inside the object constructor to register it. Then when C++ runtime deinitializes the module it will at some point after main() call your deinitialization function. That bold italic is there because you get rather loose control on when exactly it is called and that can lead to deinitialization order fiasco - be careful.
You can use a private destructor with shared_ptr
by passing in a deleter that has access to the destructor (such as a class defined as a member of SingletonTest
).
However, you need to be very careful when destroying singletons to ensure that they are not used after they are destroyed. Why not just use a plain global variable anyway?
...not exactly a direct answer, but too long for a comment - why not do the singleton this way:
class SingletonTest {
private:
SingletonTest() {}
~SingletonTest() {
std::cout << "Destructing!!" << std::endl;
}
public:
static SingletonTest& get_instance() {
static SingletonTest instance;
return instance;
}
};
Now you have a lazy singleton that will be destructed on exit... It's not any less re-entrant than your code...
You could always friend the shared_ptr (or rather scoped_ptr, which is more fitting) to allow it access to your private destructor.
Note that there's also the system atexit()
function which can register a function to call at the end of the application. You could pass a static function of your singleton that just does delete instanance;
to it.
Note that it's usually a good idea separates the class that is to be a singleton from the singleton-ness of it. Especially for testing and/or when you do need the doubleton. :)
While I'm at it, try to avoid lazy initialization. Initialize/create your singletons at startup, in a well determined order. This allows them to shut down properly and resolves dependencies without surprises. (I have had cyclic singleton hell... it's easier than you think...)
if you declare the class which does the actual delete
op as a friend (let it be shared_ptr<SingletonTest>
or some kind of default deleter) a friend, your destructor can be private.
Although i dont see any necessarity for making it private.
The first question is: do you want the singleton to be destructed. Destructing a singleton can lead to order of destruction problems; and since you're shutting down, the destructor can't be necessary to maintain program invariants. About the only time you want to run the destructor of a singleton is if it manages resources that the system won't automatically clean up, like temporary files. Otherwise, it's better policy to not call the destructor on it.
Given that, if you want the destructor to be called, there are two
alternatives: declare the single object as a static local variable in
the instance
function, or use std::auto_ptr
or something similar,
instead of a raw pointer, as the pointer to it.