Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton pattern for derivable class

In the normal singleton pattern, the singleton class is effectively "sealed" (cannot be derived):

class A
{
private:
    static A m_instance; // instance of this class, not a subclass

    // private ctor/dtor, so class can't be derived
    A();
    ~A();

public:
    static A& GetInstance() { return m_instance; }

    ...
};

How would you write a class that is meant to be derived, but whose derived class should only be instantiated once?

like image 864
user1610015 Avatar asked Nov 23 '25 16:11

user1610015


1 Answers

How would you write a class that is meant to be derived, but whose derived class should only be instantiated once?

You can use the CRTP to realize that:

template<typename Derived>
class A
{
protected: // Allow to call the constructor and destructor from a derived class
    A(); 
    ~A();

public:
    static T& GetInstance() { 
        static T theInstance; // Better way than using a static member variable
        return theInstance;
    }

    ...
};

And use that like

class B : public A<B> {
    // Specific stuff for derived class
};

Note that this way makes most sense, if the base class provides some common implementation (besides the GetInstance() function) realized, based on an interface provided by the derived class.

Whenever a call to the derived class in the base class is needed you can safely use a static_cast<Derived*>(this) to access it (no virtual or pure virtual functions needed):

 template<typename Derived> 
 void A<Derived>::doSomething {
      // Execute the functions from Derived that actually implement the 
      // warranted behavior.
      static_cast<Derived*>(this)->foo();
      static_cast<Derived*>(this)->bar();
 }
like image 160
πάντα ῥεῖ Avatar answered Nov 26 '25 11:11

πάντα ῥεῖ