Archived

This topic is now archived and is closed to further replies.

Austrian Coder

Deconstructor not called?!

Recommended Posts

Austrian Coder    122
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

Share this post


Link to post
Share on other sites
Fruny    1658
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 ]

Share this post


Link to post
Share on other sites
Austrian Coder    122
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!

Share this post


Link to post
Share on other sites
UltimaX    468
Change the CLog deconstructor to virtual ~CLog(), like the singleton.

-UltimaX-

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

Share this post


Link to post
Share on other sites
VolkerG    151
How do you actually use CLog? Where is it use and how ist it destructed? Or where should the destructor of CSingelton be called?

Share this post


Link to post
Share on other sites
Lektrix    106
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]

Share this post


Link to post
Share on other sites
UltimaX    468
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!"

Share this post


Link to post
Share on other sites
Shannon Barber    1681
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]

Share this post


Link to post
Share on other sites
UltimaX    468
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!"

Share this post


Link to post
Share on other sites