Sign in to follow this  
Antheus

C++ object lifetime

Recommended Posts

Consider this:
class LogWriter
{
public:
	~LogWriter()
	{
		m_out << std::endl;
		std::cout << m_out.str();
	}

	template < class T >
	LogWriter &operator<<( T t ) 
	{
		m_out << t;
		return *this;
	}
private:
	std::stringstream m_out;
};


class Logger
{
public:
	LogWriter info()
	{
		return LogWriter();
	}
};

int main(int argc, char* argv[])
{
	Logger l;
	l.info() << "Hello " << "World " << 15 << 'x' << " abc";
        return 0;
}

Calling a logging method ( info() ) creates a LogWriter object for the duration of the statement. LogWriter composes the log and writes out entire log in its destructor in one go. LogWriter does not get copied in return LogWriter(); I've tested with debug and release mode under mvc2005 and it behaves as expected. No double logs, no other issues, logs apear exactly when they should. But: Am I abusing something here? Somehow I'm not too happy with all that return-by-value thing. Anyone got an insight to offer?

Share this post


Link to post
Share on other sites
Looks fine to me. Although you'd probably want to make Logger a friend of LogWriter, and make the LogWriter constructor private to prevent code just creating LogWriter's whenever it wants (Unless you want to do that).

Share this post


Link to post
Share on other sites
Why not just keep writers as members of the logger, and return a pointer? Then you could have a "commit" method (or "flush" and anything else) to allow explicit writing, rather than use the end-of-life approach?

That sounds safer to me.

Share this post


Link to post
Share on other sites
Quote:
Original post by smitty1276
Why not just keep writers as members of the logger, and return a pointer? Then you could have a "commit" method (or "flush" and anything else) to allow explicit writing, rather than use the end-of-life approach?

That sounds safer to me.


So that I can return a dummy template that does nothing, and gets compiled out entirely if logger's level is higher than that particular log.

In full implementation, if a logger's level is < default level, every log statement doesn't get evaluated and doesn't generate any code. This way the low level debug logs don't even get put into executable.

Another reason is thread-safety. Having one writer only would require locking.

Share this post


Link to post
Share on other sites
What about this? It is basically the same, but suggests some possible improvements:
    {
Logger l;
{
LogWriter w = l.info();
w << "Hello " << "World ";
for ( int i = 10; i > 0; --i )
{
w << i << "...";
}
w << 15 << 'x' << " abc";
}
return 0;
}


Quote:
Original post by Antheus
LogWriter does not get copied in return LogWriter();

It may or may not get copied. It depends on the compiler and the optimization level.

As a side note, you might want to make this change:
    template < class T >
LogWriter & operator<<( T const & t )
{


[Edited by - JohnBolton on May 2, 2007 1:53:22 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this