TITLE: example implementation of the singleton pattern [ John Vlissides is a researcher at IBM and one of the authors of the Design Patterns book. He supposedly will have an article in July ?C++ Report? on designing with singletons. This tip comes from the design patterns discussion group. -adc ] RESPONSE: tim@lightstone.com (Tim Peierls at PUMICE), 22 Jan 96 We use the following preprocessor macros (!) to make it easy to declare singletons in C++ uniformly and with reasonable cleanup behavior and efficiency. However, the issue is indeed more complicated, so I look forward to a more detailed treatment in John Vlissides' column. #define DeclareSingleton(Type) \ public: \ static Type* MakeInstance(); \ static Type* Instance() { \ if (!_instance) _instance = MakeInstance(); \ return _instance; \ } \ private: \ static void CleanupInstance(); \ static Type* _instance; #define DefineSingleton(Type, Value) \ void Type::CleanupInstance() { \ delete _instance; \ _instance = 0; \ } \ Type* Type::MakeInstance () { \ atexit(&CleanupInstance); \ return (Value); \ } \ Type* Type::_instance = 0; To declare a singleton instance of a class C: class C { DeclareSingleton(C) public: // ... }; To define the instantiation, put the following at file scope in any non-header file: DefineSingleton(C, expr) where expr is an expression whose value is a pointer to the newly allocated singleton instance, for example: class CC : public C { /* ... */ }; DefineSingleton(C, new CC) The expression will be evaluated once only. Singletons will be destroyed sometime after exiting main(), in reverse order of their construction. This is not a foolproof technique however, since it doesn't prevent the user from deleting a singleton instance. There are other drawbacks as well, but the technique has worked well in practice. RESPONSE: hnkst2@lis.pitt.edu (Hanhwe han Kim) I thought that because the _instance member variable is static, it exists separately of any new'ed Singleton. Thus you needed a destructor which did: Singleton::~Singleton() { _instance = NULL; }; and a way to execute delete Singleton::Instance(); at the appropriate time. The delete should deallocate any memory for the Singleton if it has been allocated, and assign a NULL to the static _instance variable, so the next time Singleton::Instance() is called, the _instance variable is new'ed. The way that I make sure the 'delete Singleton:Instance()' gets called at the termination of a program is to define a class: class singleton_maker { singleton_maker() { Singleton::Instance(); }; ~singleton_maker() { delete Singleton::Instance(); }; }; and a static instance of the singleton_maker class at file scope: static singleton_maker the_singleton_maker; I put these in the *.cpp file with the code for the Singleton's member function definitions so the singleton_maker class is hidden from other modules. The static variable the_singleton_maker is created at program initiation and destructed at termination, and insures that the Singleton is created and deleted. This should work as long as the rules for static variables are kept the way they are. I learned this either on the comp.object newsgroup or the patterns mailing lists last year. Cheers for the originator and apologies for any incorrect implementation on my part. I *think* it works, and it *seems* to work on some test programs I did with Borland C++ 3.1 (and checking for memory leaks with BoundsChecker/Windows) but still... If anyone can see any reason why it should not work (either the idea itself using characteristics of static variables to ensure creation and destruction of Singletons or my implemenation), please let me know!! RESPONSE: tim@lightstone.com (Tim Peierls at PUMICE) [Responding to some comments by Paul J. Ste. Marie:] MakeInstance() should indeed be protected. I forget why we did it that way -- I think there was some local reason (debugging code?) that no longer applies. Thanks for pointing it out. As for setting the _instance pointer to 0 to allow later recreation of the instance: We've adopted the standpoint that a singleton instance should never be destroyed explicitly (because we want to be able to count on having the same instance throughout the execution of the program), so reconstruction is not an option for us. On the other hand, I use the technique you describe for something very similar, what I would categorize as a "Current Instance" pattern. A simple way to defend against unprivileged deletion of the Singleton through the Class::Instance() pointer is to make Class::~Class() private, but we didn't (couldn't?) incorporate that safety into the preprocessor macros. Perhaps John Vlissides' article will have a more comprehensive solution.