Sign in to follow this  
hallgeir

Implementing a "debug text output class" for my classes

Recommended Posts

hallgeir    154
Hi. :) I'm in the process of trying to clean up my code a bit, and while doing so I thought I should implement some kind of debug text outputter to use with all my classes. I did make one (a long time ago) but it's very poorly designed and I got a new idea. What I had in mind was something like this (simplified):
#include <ostream>

class Debug
{
private:
	std::ostream &outstream;
public:
	Debug(std::ostream &output);
	void print(std::string dbgtext);
};
So basically, the idea is: Let the user of the classes decide what stream the debug text should be outputted to (for instance std::cout, an instance of std::ofstream, or similar). That part is done. BUT what I also had in mind was to let that decision apply for EVERY class in my project. Or else this is pretty useless. Let's say I want to let all the debug text get outputted to a file called "debug.txt". Then I'd like to only have to call the constructor ONCE, and then let every class use that output stream. For instance: std::ofstream debugfile("debug.txt"); Debug debugobject(ofstream); should make ALL my classes (texture class, sprite class, everything) output to "debug.txt". How is the best way to achieve this? I've thought of a few options but they all seem VERY inconvenient. The ones I thought of was: - Have a reference to the debug object in every class. Unfortunately then I'd have to include the debug object in the CONSTRUCTOR of every class. - Pass the debug object as a reference to all my member functions. - Make it a global variable in my namespace. Personally I'm not very fond of this one. Neither of those options seems like a good idea to me. So how would you do it? Any suggestions? :) Thanks in advance.

Share this post


Link to post
Share on other sites
rip-off    10979
It depends on your needs. If your game is simple enough, I see nothing wrong with a global logger.

If you decide to do this, there is a neat trick. You can use the rdbuf() member of std::ostream to change the location of the output. So what you could so is:

int main()
{
std::ofstream file("debug.txt");
std::cout.rdbuf(file.rdbuf());
// and std::cerr, std::clog

std::cout << "Hello, world\n"; // <-- written to the file!
}




You could even implement your own std::streambuf to log to multiple locations at once. This way you don't have to write your own class, and you get all the benefits of a proper std::ostream (including support for user defined objects).

Even if you don't plan on using a global using this method could be handy to write the Log class itself. If you are interested here are some links:
Bregma's post towards the end.
Bregma again. [smile]
Mr Edd's blog entry on the subject.

Share this post


Link to post
Share on other sites
hallgeir    154
Cheers rip-off! Thanks for the tip. Also I will certainly look into implementing my own streambuf.

Any further tips on how to avoid using a global logger is also very appreciated. :) I might make it global, if I don't get any bright ideas (from myself or you guys) but I'd really hoped I don't need to.

Best regards

Share this post


Link to post
Share on other sites
Thergothon    160
I do what rip-off does + have a overloaded << outside of the class like this. It feels a bit nicer than having a DebugString() in every class.


template <class type>
inline std::ostream& operator << (std::ostream& stream, const vec2<type>& v) {
stream << "(" << v.x << ", " << v.y << ")";
return stream;
}

//so i can write

vec2f v;
std::cout << v << std::endl;


Share this post


Link to post
Share on other sites
hallgeir    154
Quote:
Original post by Thergothon
I do what rip-off does + have a overloaded << outside of the class like this. It feels a bit nicer than having a DebugString() in every class.


Ah cool. Good idea. *notes* :) I could really use a better way to print debug info about my classes, and this one looks exactly what I'm looking for.

Anyway, here's my plan so far. A few changes:
I think I will use std::clog / std::err consistently through my code. That means - no real need for a logging class (at least not for now). Then I'll use rip-offs suggestion about redirecting std::clog to use another stream (like a ofstream instance or cout). This can hopefully be done globally, for instance doing it once in my main function should hopefully also apply in all my classes. This remains to be tested though. :P

Thanks for the help so far! :)

Also any further tips on logging is greatly appreciated!

Kind regards

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