Quote:Original post by gregs
That said, I would use a singleton logging class over std::clog, which has platform specific behaviour, and if you're not running *nix (or a console app) you have to redirect to a file anyway.
Care to elaborate on what you mean by "platform specific behavior"?
If std::clog were insufficient for my needs, it'd be due to one of the following:
1)
Multiple filtered logging categories to care for.
2)
Multiple filtered logging levels to care for.
3)
Multiple logging destinations to care for.
4) I want to put my initialization in a constructor and forget about it.
5) Other miscellanious boilerplate.
None of these are helped by making the class a singleton instead of just a normal class. None. Zero. The cost? They're quite likely even directly hindered by it. And your immortal soul -- or at least some serious refactoring or mantinence headaches when it turns out you really need 2. Or 3. Or N. Or some other excuse to end up on
thedailywtf.com.
Worlds will not collide if two loggers are made. Even if they were (which would require some serious effort on your part), how could you trust your fellow programmers to properly mantain singletons when they can't even read the comment you made by the assert(!already_instantiated); in the constructor to that effect?
Simply put, you can't. These people are timebombs -- either convince management to fire them, or you might as well just end all the misery leading up to your project's inevitable cancellation, the ensuing layoffs, and taint on your resume. Remember: C++ lets you reuse the bullet!
There's one place that I basically use the singleton pattern: dealing with C callback libraries. But I pretend not to. I don't expose a public GetInstance(); interface -- there's only the private member
static "instance" variable, and the private static callbacks which are to be registered, and the class registers itself. I create one instance of the class as I would any other, and the constructor asserts there wasn't a previous instance, then sets "instance" to itself. It's likely not even global. If I need multiple instances? Just set up the dispatch framework from whatever get____ID() functions the API exposes, update the (de)constructor(s) to update said dispatch instead of a single instance variable... and poof! No broken code, things just don't explode if you make multiple instances of them!
I find this a lot more productive than going through the bother and effort to mentally work out of it's really reasonable to save a few keystrokes at best at the cost of locking myself into one instance on pain of structural refactor.
[Edited by - MaulingMonkey on February 13, 2007 1:23:50 PM]