Destruktor wird nicht aufgerufen?!
-
Hallo,
ich hab folgende zwei Klassen:
/////////////////////////////////////////////////////////// // omeSingleton /////////////////////////////////////////// /////////////////////////////////////////////////////////// template<typename T> class omeSingleton { private: static T* m_pSingleton; public: omeSingleton() { assert(!m_pSingleton); m_pSingleton = static_cast<T*>(this); } virtual ~omeSingleton() { assert(m_pSingleton); m_pSingleton = 0; } public: static inline void Create() { if (m_pSingleton) return; new T(); } static inline T& GetSingleton() { assert(m_pSingleton); return *m_pSingleton; } static inline T* GetSingletonPtr() { assert(m_pSingleton); return m_pSingleton; } static inline void Destroy() { if (m_pSingleton) { delete m_pSingleton; } m_pSingleton = 0; } }; template<typename T> T* omeSingleton<T>::m_pSingleton = 0;
/////////////////////////////////////////////////////////// // omeKernel ////////////////////////////////////////////// /////////////////////////////////////////////////////////// class omeKernel : public omeSingleton<omeKernel> { protected: std::list<omeSmartPointer<omeITask> > m_taskList; std::list<omeSmartPointer<omeITask> > m_pausedTaskList; public: omeKernel(); ~omeKernel(); int Execute(); bool AddTask( omeSmartPointer<omeITask>& t ); void SuspendTask( omeSmartPointer<omeITask>& t ); void ResumeTask( omeSmartPointer<omeITask>& t ); void RemoveTask( omeSmartPointer<omeITask>& t ); void KillAllTasks(); };
Mein Hauptprogramm sieht dann (stark gekürzt) so aus:
/* the application's run function */ void TestGame::Run( int argc, char* argv[] ) { // create singletons omeSettingsManager::Create(); omeKernel::Create(); omeRessourceManager::Create(); omeObjectManager::Create(); omeSoundManager::Create(); // ... // clean up singletons omeSoundManager::Destroy(); omeObjectManager::Destroy(); omeRessourceManager::Destroy(); omeKernel::Destroy(); omeSettingsManager::Destroy(); }
Jetzt sollte doch sowohl der Konstruktor der Basis-Klasse omeSingleton als auch der Konstruktor der abgeleiteten Klasse omeKernel aufgerufen werden, oder? Komischerweise wird aber der Destruktor von omeKernel nicht aufgerufen.
Woran kann das liegen?Mfg, smasher1985
-
static inline void Create() { if (m_pSingleton) return; new T(); }
da zeigt nix aufs neue T()
-
aber hier:
m_pSingleton = static_cast<T*>(this);
oder etwa nicht?
Mfg, smasher1985
-
sorry, hab mir den code nicht ganz angesehen
bist du mit diesem minimalbeispiel einverstanden:template <class T> class base { static T *ptr; public: base () { if (!ptr) ptr = static_cast<T*>(this); } virtual ~base () { cout << "base::~base\n"; assert(ptr); ptr = 0; } static void create () { if (ptr) return; new T(); } static void destroy () { delete ptr; } }; template <class T> T *base<T>::ptr; class test : public base<test> { public: ~test () { cout << "test::~test\n"; } }; int main () { test::create(); test::destroy(); }
das funktioniert bei mir.
-
jo, bin einverstanden
funktioniert bei mir auch - aber eben nur im Minimalbeispiel. Wo ist der Unterschied zu meiner Implementierung?Mfg, smasher1985
-
was tatsächlich ein problem sein kann ist diese zeile mit dem static_cast.
vergiss nicht: im konstruktor von omeSingleton ist omeKernel noch nicht fertig konstruiert. was spricht gegenvoid Create () { if (!ptr) ptr = new T(); }
-
smasher: kannst du statt dem ome vor jeder Klasse lieber ein Namespace verwenden?
-
Hab das jetzt geändert. Funktioniert einwandfrei, bewirkt aber genau das gleiche - kein Destruktoraufruf!!!
Übrigens hab ich gerade noch rausgefunden, dass auch der Konstruktor der Basisklasse nicht aufgerufen wird. Ich hatte vergessen, das vorher zu überprüfen
also kommt es bei mir zu gar keinem Konstruktoraufruf!
Mfg, smasher1985
-
De- oder Konstruktor?
ruf den destruktor in der destroy funktion einmal explizit auf.
also mit m_pSingleton->~T();
der statische typ ist nun einmal omeKernel und von daher sollte auch omeKernel::~omeKernel aufgerufen werden;
gibt einfach mal noch mehr code