Quote:Original post by swiftcoder
However, if I have read this correctly, because the data variable is static, it will never be deleted (unless you set data to 0 in the destructor of singleton_handle), and it also means the only way to delete the singleton is to let the singleton_handle go out of scope, which means we are back to scoping variables, which is exactly what the singleton and memory manager are trying to automate in the first case.
You have misunderstood some.
Because the data variable is static, you can't call delete on it. You can, however, explicitly call it's destructor (which exists for all classes), and do a placement new (calling it's constructor if it has one). The area of memory is pre-allocated and is freed up at program termination, just like any global variable (or any variable on any modern OS). It's constructor does get called* (on GCC I believe it's at the first time the static variable is ever used) and it's destructor will get called* when the program exits.
* by "will get called" I mean "if things don't seriously fubar in the program, and your compiler isn't having problems combining internal initilization/cleanup code accross DLL and EXE boundries."
singleton_handle goes in and out of scope - because it's static it's shared between all the handles.
The one problem I'm aware of with this method is the order of initialization and deinitialization - if one singleton depends on another things can get messy real fast (when one gets uninitialized before the other, usually). To explicitly (de)initialize the array, you'd need to change the definitions to something like this:
#include <new>class singleton_handle< typename T >{ static char[ sizeof(T) ] c_data;public: //note: init nor fini check if the handle has been initialized or not yet. void init ( void ) { new ((T *)c_data) T(); } template < typename Arg1T > init( const Arg1T & Arg1 ) { new ((T *)c_data) T( Arg1 ); } void fini ( void ) { ((T *)c_data)->~T(); } //note: this will fubar if things havn't been initialized properly. T & operator*( void ) { return *((T *)c_data); } //prevents casting to (const) temp var. T * operator->( void ) { return ((T *)c_data); }};template < typename T > char singleton_handle<T>::c_data[ sizeof(T) ];
edit: deleted ampersands (&) that didn't belong.