In C ++, how to initialize a static member of a private class declared inside a Singleton template?

Well, I just have to say that I want to create a Singleton base class that I can inherit, and the way I want to achieve this is with a template.

To avoid memory leaks, I do not use the pointer to the instance directly, but a private class that will handle pointer deletion.

Here is my actual code (not working):

template <typename T> class Singleton
{
private:
    class PointerInstance
    {
    private:
        T* instance;
    public:
        PointerInstance() : instance(0) {}
        ~PointerInstance() { delete instance; } // no memory leak !
        T* Get()
        {
            if ( !instance ) {
                instance = new T();
            }
            return instance;
        }
    };
    static PointerInstance PInstance;
public:
    static T* pGetInstance(void)
    {
        return PInstance.pGet();
    };
protected:
    Singleton(void){};
    ~Singleton(void){};
};

And this is what a typical derived class declaration should look like:

class Child : public Singleton<Child>
{
    friend class Singleton<Child>;
    Child();
    // etc...
};

Basically what is missing is an instance of PInstance for every T class that I do as Singleton.

: Singleton.h, , , ?

(: Singleton ++?)

+3
4

CRTP :

template <class T>
class Singleton
{
  friend class T;
private:
  Singleton() {};
  ~Singleton() {};
  Singleton(const Singleton&); // not implemented
  const Singleton& operator=(const Singleton&); // not implemented

public:
  static T* pGetInstance()
  {
    static T theInstance;
    return &theInstance;
  }
};

, .

+2
template <typename T> 
typename Singleton<T>::PointerInstance Singleton<T>::PInstance;

. , , PInstance , , pGetInstance PInstance , . .

+5

, Loki, SingletonHolder<> ?

0

-, , . .

, ( -, , ), Singleton. , .

, - boost:: once. - , Foo - .

3 Foo private

Foo* Foo::instance = NULL;
boost::once_flag Foo::flag = BOOST_ONCE_INIT;
void Foo::init()
{
   Foo::instance = new Foo;
};

Foo & Foo::getInstance()
{
   boost::call_once(init, Foo::flag);
   return *Foo::instance;
}

Foo .

, - , . boost:: once ( : beware), , -, boost::, :: bind .

To remove Singleton, you can create boost :: shared_ptr at the compilation unit level and bind your pointer to it and use a custom remote element that is a static member of your class so that the removal can remain private. Your sender will be able to call deletion, though, and your init function will have access to the deleter function (which is also private) to initialize shared_ptr with it.

0
source

Source: https://habr.com/ru/post/1769339/


All Articles