C++ Singleton vs C-style "Singleton"

Started by
4 comments, last by nmi 17 years, 8 months ago
What are the pros/cons of doing a real C++ singleton class over a fake C-style "singleton" where the header file contains the accessor functions and the "member variables" for the C-style singleton are static globals in the *.c file? Assume that the system would not be used in any inheritance heirarchy, so rule that out. In my case, having the constructors in C++ aren't one of the advantages b/c I am doing a logging system, so I would have to call some form of an Intialize() function in either case to specify the file to open. Also, I could still wrap a namespace around the C-style singleton to prevent naming conflicts. I guess my main reason for asking is that the C++ syntax in this case seem much worse (longer): C++ Singleton Syntax: Logger::GetInstance()->Initialize(filename); ... Logger::GetInstance()->Log("Message"); C-style "Singleton" Syntax: Logger_Initialize(filename); ... Log("Message");
<a href="http://www.slimcalcs.com>www.slimcalcs.com
Advertisement
Both are as bad as each other. Personally I'd just go with a global variable (ie. like cout).
The C++ singleton is an object, it may therefore inherit from other objects and be passed as argument to the related functions. For instance, an ostream singleton like std::cout (even if wrapped in an access layer) can be used with any ostream-friendly function.

You could also make the Log function static and have it call getInstance internally if you want to make it shorter:
//headerpublic:  static void Log(char* str);//sourcevoid Logger::Log(char* str){  GetInstance()->private_func_that_writes_to_file(str);  //or since you can access privates why not:  // instance->pricate_func .... (assuming you can initialize first  // which sets instance).}//To use:Logger::Log("Log this");


Greetings.
Not sure what you mean by "system would not be used in any inheritance heirarchy". Thus I might say few irrelevant things to your question, live with it ;-). You are forgetting one minor detail. Singleton in CPP can me more than "static methods static members". Singleton is an object. It can be derived from other classes, it can override methods, it can be extended by other classes, you can use templates when it's within classes, etc..

A good example would be a prototype class.

// initialization stage
Factory<Geometry>::GetSingleton().Register("Point", new Point());
Factory<Geometry>::GetSingleton().Register("Circle", new Circle());
Factory<Geometry>::GetSingleton().Register("Polygon", new Polygon());

// using stage
Geometry* circle = Factory<Geometry>::GetSingleton().CreateObject("Circle");

Point,Circle and Polygon implement "Clonable" interface. Note that this code is not exception safe.

Now I want to create all kinds of Animals.

Animal* tiger = Factory<Animal>::CreateObject("Tiger");
Animal* fish = Factory<Animal>::CreateObject("Fish");

I am sure you got the idea by now. It adds more reusability.


Try creating such Factory facility with classes ;-)

Other than that, one of the advantages in CPP is the scope rules, so that every method of the singleton class is accessed through name of singleton class and doesn't pollute global namespace.

In the days I was coding in C, I did the Logger class just the way you've suggested in your post.

About the reason for asking the question. I prefer longer and clearer code. Nowadays there are tools like visual assist or built-in intellisense in IDE, so writing that down is not big deal, nor does it take much time. Having a static method ::GetInstance or ::GetSingleton gives me additional information behind the scene about the fact there's only one instance of that class.

you could use MACROS inside your CPP code:

#define Logger Logger::GetInstance()

Logger->Log("Message, viola! :-)");


As conclusion, use CPP singletons. They are nice and lovely creatures (:

HTH,
Shimon
"If you're stuck, ask for help. If you keep running up against the same wall, take a break and see if you can find a different wall."
Quote:Original post by scottdewald
I guess my main reason for asking is that the C++ syntax in this case seem much worse (longer):

C++ Singleton Syntax:
Logger::GetInstance()->Initialize(filename);
...
Logger::GetInstance()->Log("Message");


Create a global inline function that will do the job:
static inlinevoid Log(char* msg){  Logger::GetInstance()->Log(msg);}

This topic is closed to new replies.

Advertisement