Sign in to follow this  
scottdewald

C++ Singleton vs C-style "Singleton"

Recommended Posts

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");

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
You could also make the Log function static and have it call getInstance internally if you want to make it shorter:

//header
public:
static void Log(char* str);

//source
void 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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 inline
void Log(char* msg)
{
Logger::GetInstance()->Log(msg);
}


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