00001 /* 00002 * Copyright (c) 2004 CSIRO ICT Centre 00003 * 00004 * $Id: Destroyer.h 587 2004-12-03 15:06:33Z nch $ 00005 */ 00006 00007 #ifndef DESTROYER_DEFINED 00008 #define DESTROYER_DEFINED 00009 00010 /* 00011 * Destroyes a singleton. 00012 * 00013 * Taken from: 00014 * 00015 * http://www.sigs.com/publications/docs/cppr/9606/cppr9606.c.vlissides.html 00016 * 00017 * which was published in C++ Report sometime ... 00018 * 00019 * Note: doesn't work with the g++ compiler prior to version 2.8 due 00020 * to its lack of support for templated friend classes. 00021 */ 00022 00023 00024 template <class DOOMED> 00025 class Destroyer 00026 { 00027 public: 00028 Destroyer(DOOMED * d = 0); 00029 00030 ~Destroyer(); 00031 00032 void setDoomed(DOOMED * d); 00033 00034 private: 00035 DOOMED * m_doomed; 00036 00037 // Prevent users from making copies of a 00038 // Destroyer to avoid double deletion: 00039 Destroyer(Destroyer<DOOMED> const &); 00040 00041 Destroyer<DOOMED> & operator=(Destroyer<DOOMED> const &); 00042 }; 00043 00044 00045 template <class DOOMED> 00046 Destroyer<DOOMED>::Destroyer(DOOMED * d) 00047 : m_doomed(d) 00048 { 00049 } 00050 00051 template <class DOOMED> 00052 Destroyer<DOOMED>::~Destroyer() 00053 { 00054 delete m_doomed; 00055 } 00056 00057 template <class DOOMED> 00058 void Destroyer<DOOMED>::setDoomed(DOOMED * d) 00059 { 00060 m_doomed = d; 00061 } 00062 00063 template <class DOOMED> 00064 Destroyer<DOOMED>::Destroyer(Destroyer<DOOMED> const &) 00065 { 00066 } 00067 00068 template <class DOOMED> 00069 Destroyer<DOOMED> & 00070 Destroyer<DOOMED>::operator=(Destroyer<DOOMED> const &) 00071 { 00072 return *this; 00073 } 00074 00075 00076 #define DestroyerFriend(x) friend class Destroyer<x>; 00077 #define DestroyerDefine(x) static Destroyer<x> s_destroyer; 00078 #define DestroyerDeclare(x) Destroyer<x> x::s_destroyer; 00079 #define DestroyerInit(x) s_destroyer.setDoomed(x); 00080 00081 00082 #endif // DESTROYER_DEFINED