Deconstructor not called?!

Started by
8 comments, last by Austrian Coder 20 years, 7 months ago
Hello! I have this situation:

class MY_API CLog : public Singleton<CLog>
{
public: 
	CLog();		// use default log file (log.txt)

	CLog(String FileName);

	~CLog()		{ Close(); }
		
	void Message(String Message);

	finline void SetForceFlush(const bool v)	{ m_ForeFlush = v; }
	finline bool GetForceFlush() const			{ return m_ForeFlush; }

	// nice operator :)

	template<class T> CLog &operator<<(const T& output)
	{
		Guard(template<class T> CLog &operator<<(const T& output))

		m_LogStream << output;
		if (m_ForeFlush) m_LogStream.flush();
		return *this;

		Unguard();
	}
		
private:
	std::ofstream	m_LogStream;
	bool			m_LogOpen;
	bool			m_ForeFlush;

	inline void Open(String Filename);	// with this function we open our logfile

	inline void Close();				// with this function we close our logfile

	};
And here the Singleton:

template<typename Type>
class Singleton
{
protected:
	Singleton()		{}
	virtual ~Singleton()	
	{ 
		if (ms_pGlobalInstance) 
		{ 
			delete ms_pGlobalInstance; 
			ms_pGlobalInstance = 0;
		} 
		else
		{}
	}
	
private:
	static Type* ms_pGlobalInstance;
	
public:
	inline static Type* GetInstance()
	{
		if (!ms_pGlobalInstance)
		{
			ms_pGlobalInstance = new Type();
		}
	
		return ms_pGlobalInstance;
	}
};
	
template <typename Type>
Type* Singleton<Type>::ms_pGlobalInstance = 0;
So.. now if the app closes then the deconstructor of the singleton is called. And this should call the singleton of the CLog class. But the Close() function is never called. Where is my mistake? Thanks, Christian
Advertisement
What leads you to believe your destructor isn''t called ?
How is the application closed ? (hint - exit() is a C function which knows nothing about destructors)

[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
This is why the deconst. is called:

inline void CLog::Close(){	Guard(CLog::Close);	if (m_LogOpen)	{		m_LogStream << "-------------------------------------" << std::endl;		// get time again		struct tm *pTime;		time_t ctTime; 		time(&ctTime);		pTime = gmtime(&ctTime);		m_LogStream << "Logfile closed at " << pTime->tm_hour << ":" << pTime->tm_min << ":" << pTime->tm_sec << std::endl;		// close file now		m_LogStream.flush();		m_LogStream.close();		m_LogOpen = false;	}	Unguard();}


I never see this line "Logfile closed at..." in my logfile!
Change the CLog deconstructor to virtual ~CLog(), like the singleton.

-UltimaX-

"You wished for a white christmas... Now go shovel your wishes!"
How do you actually use CLog? Where is it use and how ist it destructed? Or where should the destructor of CSingelton be called?
quote:Original post by UltimaX
Change the CLog deconstructor to virtual ~CLog(), like the singleton.

If a base class's member is declared as virtual, it will be resolved using the virtual function mechanism in the derived class(es) regardless of whether or not the keyword 'virtual' is used again in the derived classes' declaration.
class Base{public:    virtual ~Base();  // virtual...}; class Derived : public Base{public:    ~Derived();  // virtual here, too...};

Incidentally, it's 'destructor', not a 'deconstructor'.

As Fruny implied, the correct destructors should be being invoked correctly.

Also the order is different to what you stated, Austrian Coder. CLog's destructor is called first, and then Singleton's is called.

[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || MSVC++ Library Fixes || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on September 1, 2003 6:05:26 PM]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
LOL, ooops. Why in the hell did I put deconstructor? Oh well. Anyway, heres an actual quote from "Game Programming Gems 2" (Page 23 if you have it)

Quote
"We need to always include a virtual destructor in our abstract interfaces. If we don''t, C++ will automatically generate a nonvirtual destructor, which will cause the real destructor of our specific implementation not to be called (And that is usually a hard bug to track down). Unlike normal member functions, we can''t just provide a pure virtual destructor, so we need to create an empty function to keep the compiler happy."

So is it talking about any derived class or just pure virtual classes? Thats why I mentioned that. I might be confused now...

-UltimaX-

"You wished for a white christmas... Now go shovel your wishes!"
destructor not "deconstructor".

quote:
So is it talking about any derived class or just pure virtual classes?

You have to know what you're doing. If a class has any virtual methods (pure or not), it probably ought to have a virtual dtor.

What matters is what creates the class, and what destroys it. If the destroyer knows the exact type, the dtor doesn't need to be virtual. But if we do thing like:
Base* new_object = CreateMeAnObject(some_id);delete new_object;  

We need a virtual dtor, because we destroy the object from a base class pointer.



RealClass* obj = new RealClass;delete obj;  

No virtual dtor required (still works if it has one).


[edited by - Magmai Kai Holmlor on September 1, 2003 8:58:59 PM]
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
quote:Original post by Magmai Kai Holmlor
destructor not "deconstructor".

quote:
So is it talking about any derived class or just pure virtual classes?

You have to know what you''re doing. If a class has any virtual methods (pure or not), it probably ought to have a virtual dtor.

What matters is what creates the class, and what destroys it. If the destroyer knows the exact type, the dtor doesn''t need to be virtual. But if we do thing like:
Base* new_object = CreateMeAnObject(some_id);delete new_object;   

We need a virtual dtor, because we destroy the object from a base class pointer.



RealClass* obj = new RealClass;delete obj;   

No virtual dtor required (still works if it has one).


[edited by - Magmai Kai Holmlor on September 1, 2003 8:58:59 PM]


First of all, I know it''s destructor and not deconstructor. I have no clue why I typed deconstructor. Lektrix already mentioned that, so that was unnecessary.

With that said, I understand now. I just probably misinterpreted
Noel''s statement. Thanks for the explanation Magmai, I do appreciate it.

-UltimaX-

"You wished for a white christmas... Now go shovel your wishes!"
Thanks people - it seems to work now.

This topic is closed to new replies.

Advertisement