fazineroso
fazineroso

Reputation: 7466

Why does this singleton implementation use a private class (C++)?

So I am working with some new code from a supplier's app, and I observed that for one of their libraries, they are using a Singleton pattern. There they use a Helper to instantiate the singleton. Why is that necessary?

library header file:

Class LibExample {

public:
    static LibExample* getInstance();

private:
    class Helper {
    public:
        Helper() {
            libExampleInstance = new LibExample();
        }
        ~Helper() {
            delete libExampleInstance;
        }

        LibExample* libExampleInstance;
     };

    static LibExample* m_instance;

    LibExample();
    virtual ~LibExample();
    LibExample (const LibExample& ) {};
    LibExample& operator=(const LibExample&) {
        return *(LibExample::getInstance());
    }
};

In the .cpp file:

LibExample* LibExample::m_instance = NULL;

LibExample* LibExample::getInstance() {
    static Helper instance;
    if(m_instance == NULL) {
        m_instance = instance.libExampleInstance;
        int ret = m_instance->init();
        if(ret < 0) {
           m_instance = NULL;
        }
    }
    return m_instance;
}

Upvotes: 3

Views: 66

Answers (1)

rocambille
rocambille

Reputation: 15986

There they use a 'Helper' to instantiate the singleton. Why is that necessary?

It is not. The Helper may be used here to allows the m_instance == NULL test, and call init when first using getInstance, but init could have been run in LibExample constructor as well. There may be an obscure reason but IMHO this design is just overcomplicated.

You could have:

Class LibExample {

public:
    static LibExample* getInstance();

private:
    LibExample();
    virtual ~LibExample();
    LibExample (const LibExample& ) {};
    LibExample& operator=(const LibExample&) {
        return *(LibExample::getInstance());
    }
};

LibExample* LibExample::getInstance() {
    static LibExample instance;
    static LibExample* p_instance = NULL;
    if(p_instance == NULL) {
        int ret = instance.init();
        if(ret >= 0) {
            p_instance = &instance;
        }
    }
    return p_instance;
}

EDIT:

As pointed by @SingerOfTheFall in the comments:

I think this is done to implement some kind of a late initialization: if init() fails the first time, the singleton itself doesn't need to be re-constructed, and it will try to re-initialize itself the next time the instance is called.

Still Helper is not necessary: I modified my code accordingly.

Upvotes: 2

Related Questions