13

When designing singletons, why is the constructor made protected and not private? This is based on what I've seen over the web.

We want to control the number of instances made of that class, fair enough, but why protected? Wouldn't private do the trick as well?

Yuck
  • 49,664
  • 13
  • 105
  • 135
Ron_s
  • 1,429
  • 1
  • 14
  • 24
  • 9
    If someone has decided that singletons are a good idea, then you should expect their code to have other nonsensical design decisions, and shouldn't try to learn anything from it. – Mike Seymour Aug 31 '11 at 11:59

3 Answers3

9

Firstly, Singletons in the vast majority of cases are a bad idea (Why?). Use them even less than global variables.

It's so that subclasses can instantiantiate the Singleton base class, returning it as a part of itself in it's own GetInstance()-type function. This is the reason that it is done in Design Patterns. Therefore it's only really relevent if you plan on inheriting from the Singleton.

GoF says, (page 130, Subclassing the Singleton class);

A more flexible approach uses a registry of singletons. Instead of having Instance define the set of possible singleton classes, the singleton classes can register their singleton instance by name in a well-known registry.

In using a registry of singletons, a protected constructer in the base Singleton is still required (according to the implementation given)

In short; Make it protected if you plan on inheriting from the Singleton. Otherwise, go with private.

Seb Holzapfel
  • 3,793
  • 1
  • 19
  • 22
  • @dj aqeel "Globals and singletons are already well-known as a design antipattern" http://neugierig.org/software/chromium/notes/2011/08/static-initializers.html – Eddy Pronk Aug 31 '11 at 12:09
  • 1
    @dj: (a) Globally-accessible objects remove structure from the design, making it hard to keep track of dependencies between objects. This makes large projects harder to maintain. (b) Objects that enforce a particular lifetime management make testing harder, as they can't be created and destroyed during a test. Perhaps the `protected` constructor nonsense in this question is an attempt to reduce that effect; a `public` constructor would be better still. (c) The "static initialisation fiasco" and thread-safety issues make them hard to implement correctly in C++03 (although C++0x will fix that). – Mike Seymour Aug 31 '11 at 12:11
4

Using singletons is bad. Period.

That said, the constructor can be private, no problem. But what if you want to derive another singleton from your singleton(as if having one singleton wasn't bad enough)? In that case the derived class needs access to the base singleton constructor.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • but doesn't that let you bypass the singleton property? – Jason S Aug 31 '11 at 11:56
  • @Jason S: You can bypass pretty much everything. Doesn't mean you should – Armen Tsirunyan Aug 31 '11 at 11:56
  • @Jason S It can. I don't have my copy of GoF at work, but I believe they point out the potential problems with subclassing a Singleton and might provide alternative options/solutions. – Thomas Owens Aug 31 '11 at 11:57
  • 7
    I really want to +1 this, but singletons aren't bad **in all cases**. They're very often misused but don't hold that against the pattern! – Yuck Aug 31 '11 at 11:58
  • Let's assume you really need a singleton (I don't care if that's "impossible", let me make my argument). If it lets you bypass the "only one class restriction", wouldn't it be better to just drop the thing and use a global? – R. Martinho Fernandes Aug 31 '11 at 11:58
  • @Yuck: They are easy to code, but in large projects they do tend to mess things up. – Armen Tsirunyan Aug 31 '11 at 11:58
  • But constructor is not inherited , then what's the difference if we put in the the private ? Am I wrong ? – Ron_s Aug 31 '11 at 12:10
  • @Ron_s: You're wrong: What is inherited and what is accessible are two different things. Private functions are only accessible in the class, not the derived classes – Armen Tsirunyan Aug 31 '11 at 12:14
  • Okay , I got you.The Ctor of the base class is needed when creating the the Derived. for example: #include using namespace std; class A { protected: A() {} }; class B : public A { public: B() {} }; int main() { B b; return 0; } // if the Ctor of A was in the private , we won't be able to create a B instance .. thanks Armen :) – Ron_s Aug 31 '11 at 12:19
  • 1
    @Ron_s: That's right. I don't understand why you included `` in your example though :)))) – Armen Tsirunyan Aug 31 '11 at 12:22
  • I have a ready .cpp file for changes and program-tests , sometimes I use cout and his friends , so I just copy-pasted it (sorry) :) – Ron_s Aug 31 '11 at 12:26
  • 2
    @Ron_s: `cout` is definitely female, I object to your presumption of male domination. – Kerrek SB Aug 31 '11 at 12:32
0

It's all about inheritance. class lazy_singleton: public singleton {}; will be the same singleton with singleton constructor

friendzis
  • 799
  • 6
  • 17