Re: StateFull vs Stateless Singleton
On 5 juuli, 17:38, James Kanze <james.ka...@gmail.com> wrote:
On Jul 5, 12:31 am, =D6=F6 Tiib <oot...@hot.ee> wrote:
On 4 juuli, 23:58, sebastian <sebastianga...@gmail.com> wrote:
[...]
Looks as beautiful like any other reinvented square wheel. The
requirements seem to be that such code must work:
int main( void )
{
{
foo a;
foo::instance( ).bar( );
}
foo c; // Second singleton and *NO* Whoops
foo::instance( ).bar( );
}
Not sure why someone needs to have global state? Typical
example of singletons is a logger. Huh? So ... OK. What if
i need to have separate logs from different modules? I will
then need new class for each log to have separate singleton
logger for each module? Nonsense.
So your log manager is a singleton. Somewhere, there must be
a single bit of code which reads the configuration file for the
log.
I am not saying there may not be single instances of something. I am
saying that these should not be in some global state, so there is
danger to produce multiple by mistake or copy it and so it has to be
prevented by singleton pattern. Singular state is perfectly normal.
Where it is needed hide it into implementation to keep interface
laconic. That log configuration should be internal property of logging
framework and not some global self-owned state for anyone to ask
instance() for. Not even as private static member. Translation unit
local is perfect. Then it is function debugging::log() that consults
with private log manager (if there exist such) to find out where it
logs and how (if that differs) and not everyone typing nonsense like:
debugging::LogManager::instance().produceLogger().doYourTrick("bla
bla");
Similarly, the configuration manager is a singleton.
Depends what it manages. If "configuration" of dynamically loadable
modules then such thing must be there, but i would call it
"application" object (or its "configuration" member). If these are
module settings then these belong to each module. It is sad that C++
does not contain concept of dynamically loadable modules.
As is the code which captures the command line and its options.
Command line is passed to main() and so main() passes it to some
singleton? Why it should be a singleton? These are command line
arguments for something that will be further called by main(). Why
there must be a global singleton that holds its options? However that
does not worry me, after all there are very few things that directly
depend on command line and that command line does not likely change
during program run.
In a multithreaded application, the thread manager (which ensures
e.g. a clean shutdown) must be a singleton.
At the moment yes, application (or some framework that it uses) has to
orchestrate shutdown itself. Again, when i do not get rid of single
things then i do not like "ShutDownManager::instance().doIt()". I
prefer to have shutDown() function. If nothing else then faking it for
a unit test is lot cheaper.
What if i need to have separate logs from different threads?
Then that Logger::instance() should give me "different"
singletons based on thread ID? Huh? Why it can't just be
debugging::log() and where it logs is its internal business,
no global state no nothing?
Huh? What is debugging::log()? (The syntax suggests a static
class member. A class instance function, in sum. So that its
data is a "singleton".)
No, i meant a namespace, sorry for not being clear there.
debugging::log() like std::sort(). Actually i suggest to wrap logging
into macro anyway. Some useful information like file/function/
linenumber are impossible to gather in a generic way without macros
involved.