0

There are many folks out there that claim their singleton implementation to be robust and general because it uses metaprogramming constructs.

My goal is to enforce a singleton policy onto a derived class so that I do not have to explicitly (manually) declare the derived class' constructors as private. I think there's a way to naively add the instance static variable and the getter as a policy by making the templated singleton a friend of the class you derive. But that's not at all elegant.

I started with this code, that, among other things, is given as being a correct (i.e. complete) design of a singleton, while it is clearly allowing for multiple instances:

template <class CWrappedClass> class CSingleton { protected: static CWrappedClass* ms_instance; private: CSingleton(){} CSingleton(const CSingleton& ) {} CSingleton& operator = (const CSingleton&) {} public: static CWrappedClass& GetInstance() { if (ms_instance == NULL) ms_instance = new CWrappedClass; return *ms_instance; } }; template <class CWrappedClass> CWrappedClass* CSingleton<CWrappedClass>::ms_instance = NULL; 

And a singleton client of this "policy", using CRTP:

class CThing : public CSingleton<CThing> { // friend class CSingleton<CThing>; // only if ctor is private! public: void DoNothing() { std::cout<<" Nothing \n"; } CThing() { std::cout<<" single "; } }; 

NOTE this is not a correct implementation of a CRTP Singleton policy, it's merely part of the question!

The code won't compile as is. The base singleton policy class has its constructor declared private, so it can't support derived instances unless the child is a friend of this class. People usually make the constructors protected, which means there's nothing to keep a user from making derived class non-singletonian.

Problem/Question: Is there any mechanism to enforce a singleton policy without having to make the derived class' constructors private manually?

5
  • 1
    IMHO you never need a singleton. Just instantiate it once and that's it. What is so bad about singletons? Commented Nov 12, 2012 at 16:14
  • This is a classic topic, let's tolerate the singleton pattern for now, just for educational purposes, by solving this conditioned puzzle. There are tons of reasons for not using it, but I would like not to have them written down in any answers to this thread :).. Commented Nov 12, 2012 at 16:16
  • I don't see a question here. What, exactly, is the question? Commented Nov 12, 2012 at 16:16
  • friend class CWrappedClass; work, by any chance? Commented Nov 12, 2012 at 16:19
  • Singleton should have a protected constructor. CThing should have a private constructor and make its base class a friend. Commented Nov 12, 2012 at 16:21

1 Answer 1

2

In case you do wish to use this pattern:

  1. Constructor of the template should be protected, not private, so that the derived class has access to it. Otherwise its own constructor cannot construct the base class.

  2. Derived class can make the template (which is its base class) a friend and have a private constructor.

Alternatively, have a macro that you implement that actually constructs the instance from the derived class in its compilation unit. When I did use a similar model (by force, fixing code that used singletons and I coudn't change that, only the way the actual singleton was implemented), I went for this option, which actually went through a boost::once construct in its .cpp file.

Sign up to request clarification or add additional context in comments.

3 Comments

At the moment, this strategy is the only one. I could close the question as it seems there is no other way other than making the derived classes have their constructor(s) private.
The derived classes should have private constructors so you can't just create one from anywhere, thus enforcing their singleton status.
Ok, going for the macro helper as it's a bit easier than writing by hand the constructors and the '=' operator in the private section. Question closed, thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.