Quick question. Is there anyway to inherit a singleton so that the child class is a singleton? I have searched around but every singleton I can find is implemented per class, and not in a generic fashion.
Yes there is a generic way. You can implement a Singleton via CRTP, like:
template<typename T>
class Singleton
{
protected:
Singleton() noexcept = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
virtual ~Singleton() = default; // to silence base class Singleton<T> has a
// non-virtual destructor [-Weffc++]
public:
static T& get_instance() noexcept(std::is_nothrow_constructible<T>::value)
{
// Guaranteed to be destroyed.
// Instantiated on first use.
// Thread safe in C++11
static T instance{};
return instance;
}
};
then derive from it to make your child a Singleton:
class MySingleton: public Singleton<MySingleton>
{
// needs to be friend in order to
// access the private constructor/destructor
friend class Singleton<MySingleton>;
public:
// Declare all public members here
private:
MySingleton()
{
// Implement the constructor here
}
~MySingleton()
{
// Implement the destructor here
}
};
Live on Coliru
A singleton has a static getInstance() method that upon first invocation creates the single instance of the class, and therefore is statically-bound to the type of singleton class being instantiated. I don't see the immediate utility of having a Singleton hierarchy. But if you insist on having one, you might consider making the getInstance method virtual and overriding it in the class extending your parent Singleton.
class Singleton {
public virtual Singleton * getInstance() const
{
// instantiate Singleton if necessary
// return pointer to instance
}
...
};
class MySingleton : public Singleton {
// overrides Singelton's getInstance
public virtual MySingleton * getInstance() const
{
// instantiate MySingleton if necessary
// return pointer to instance
}
};
Of course, a robust implementation would store and return smart pointers.
Related
Providing the simple implementation of a Singleton class below. It is possible for anybody to call the destructor as long as s/he has the reference to the singleInstance.
class SomeClass {
public: /** Singleton **/
static SomeClass &instance() {
static SomeClass singleInstance;
return singleInstance;
};
private:
SomeClass() = default;
SomeClass(const SomeClass&) = delete;
SomeClass &operator=(const SomeClass&) = delete;
};
To prevent such a nonsense operation, should we declare the destructor of Singleton classes in a private context?
class SomeClass {
// ... same above
private:
~SomeClass() {}
};
The problem exists also for the heap-allocated Singleton instances. Consider the implementation below.
class SomeClass {
public: /** Singleton **/
static SomeClass &instance() {
static SomeClass *singleInstance = nullptr;
if(!singleInstance) {
singleInstance = new SomeClass;
}
return *singleInstance;
};
private:
SomeClass() = default;
SomeClass(const SomeClass&) = delete;
SomeClass &operator=(const SomeClass&) = delete;
// ~SomeClass() {}
};
int main()
{
SomeClass *const ptr = &SomeClass::instance();
delete ptr; // Compiles if destructor isn't private and vice versa
return 0;
}
Should we declare the desctructor of a Singleton class as private?
Yes.
Sidenote: Singleton pattern is rarely necessary, an using it unnecessarily is a common anti pattern.
I'm implementing a static polymorphism:
template<typename T>
class Base {
public:
void method() {
// do something
impl();
// do something else
}
void impl() { // intended to be private
static_cast<T*>(this)->impl();
}
};
class Derived : public Base<Derived> {
public:
void impl() { // intended to be private
}
};
This code is a static implementation of a dynamic polymorphic classes where void impl() was pure virtual. So the base class was abstract.
Now these classes implement static polymorphism and therefore don't have pure virtual functions.
Is it possible to make Base class abstract, so that objects of this class can't be created?
You can use a protected destructor and constructors:
template<typename T>
class Base {
public:
void method() {
// do something
impl();
// do something else
}
void impl() { // intended to be private
static_cast<T*>(this)->impl();
}
protected:
Base() = default;
~Base() = default;
// If you don't want to implement proper copying/moving:
// Base(const Base&) = delete;
// Base(Base&&) = delete;
// Base& operator=(const Base&) = delete;
// Base& operator=(Base&&) = delete;
};
This will even disallow a derived class's member functions to create base class objects, as well as trying to delete a pointer whose static type is Base<T>.
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?
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();
}
How can I create a constructor which only can be called by its own class? So when I have a Class Foo only make the constructor callable if it's called from a static member of Foo.
You can make the constructor private:
class Foo
{
private:
Foo();
public:
static Foo* Create() { return new Foo(); }
}
And use the static method Create() to create an instance of the class.
Major reasons for making the constructor static can be to force the creation of the object by a factory, by a singleton, or in case when a class contains only static methods. I.e., a typical singleton implementation (single-threaded, for simplicity):
class Singleton
{
private:
Singleton();
public:
static Foo& GetInstance() { static Foo Instance; return Instance; }
}
Make the constructor private:
class Foo
{
Foo();
public:
static void usesFooConstructor();
static Foo& makeInstance(); // only if you need a handle to an instance
};
How can I return the object or call the getInstance of derived class whose base is singleton
You would have to use virtual static method, which is not supported in C++ (It's supported in Delphi, as far as I remember - a curiosity).
You have to decide, whether there's only one instance of both classes or of each class (eg. if you create a Derived instance by GetInstance, should you be able to create Base instance).
There is no way to solve this problem inside these classes, you have to create a class factory. Something like that (I've ommited the singleton implementation to make the idea more clear - obviously you know, how to implement one)
class SingletonFactory
{
template<typename T>
static T * GetInstance()
{
return T.GetInstance();
}
};
class Base
{
friend class SingletonFactory;
private:
static Base * GetInstance()
{
// ...
}
protected:
Base()
{
}
};
class Derived : public Base
{
friend class SingletonFactory;
private:
static Derived * GetInstance()
{
}
protected:
Derived()
: Base()
{
}
};
// (...)
Derived * d = SingletonFactory::GetInstance<Derived>();