I just want to know when should I use singleton class over static object and vice versa. Because same can be used to have only one instance. One reason I can guess about the storage difference in memory. Is there any other reason to choose one over the other.
2 Answers
The main difference between a singleton and a static object is that the singleton guarantees that there can only be one instance of a particular class type, whereas a static object is only a single instance of a particular type. This means that the fundamental difference is whether it makes sense for the class to have multiple instances or not. For example, let's say that you have a factory that builds widgets.
class WidgetFactory {
public:
int numberOfWidgetsBuiltInTheWholeApplication();
// returns number_of_widgets_built
std::shared_ptr<Widget> build();
// increments number_of_widgets_built
private:
size_t number_of_widgets_built;
};
Let's also assume that we want to guarantee that we can determine the number of Widgets that were created in the entire application, and enforcing that there is only one WidgetFactory is an easy way to do this. This is where we would use a singleton. If we were to just use a static object, like this:
WidgetFactory& theWidgetFactory()
{
static WidgetFactory widget_factory;
return widget_factory;
}
we would have no guarantee that theWidgetFactory().numberOfWidgetsBuiltInTheWholeApplication() was actually the real total, since someone else could come along and make their own WidgetFactory instance.
However, if we make WidgetFactory be a singleton, we now have that guarantee. We could do that perhaps by making the constructors private:
class WidgetFactory {
public:
int numberOfWidgetsBuiltInTheWholeApplication();
std::shared_ptr<Widget> build();
private:
WidgetFactory();
WidgetFactory(const WidgetFactory &); // not implemented
friend WidgetFactory& theWidgetFactory();
};
Now only theWidgetFactory() function is allowed to create the instance. There are other ways that we could make numberOfWidgetsBuiltInTheWholeApplication() function properly without using a singleton, but perhaps in some situations that solution is more complicated or has other downsides.
2 Comments
where only static initialization is involved, a global constant is ok. where dynamic initialization is involved, you want to avoid the static initialization fiasco. hence if you must, singleton should be preferred.
however, mutable singletons are generally just global variables in disguise.
therefore, to the extent practically possible, avoid them.
int& f() { static int rc{}; return rc; }- this makesinta singleton of some sort...?!?