Deleting copy/move constructor for singleton class in cpp

132 views Asked by At

The below code snip from a singleton class(claiming to be!!) is used for returning the singleton instance of the class using reference. The copy/move constructors were not marked as deleted in this case.

    static SingletonTestClass& getInstance() {
        static SingletonTestClass handler;
        return handler;
    }

And there were two flavours of usages as follows

  1. Getting the instance to a local variable and use that to invoke class functions
    auto handler = SingletonTestClass::getInstance();
    handler.someApi();
  1. Directly calling the "someApi" like shown below.
    SingletonTestClass::getInstance().someApi();

For case 1 there is a copy constructor involved wherein in case of 2 its not. I am interested in knowing how case 2 is working inernally.

Note: I have refactored the original code to the following style assuming this is a good way of implementing singleton and would like to know if there is a better way to do this.

    public:
    static SingletonTestClass* getInstance() {
        static SingletonTestClass handler;
        return &handler;
    }

    /* Note: Do not provide copy/move semantics */
    SingletonTestClass(const SingletonTestClass& ref) = delete;
    SingletonTestClass(SingletonTestClass&& ref) = delete;
    ~SingletonTestClass() = default;
1

There are 1 answers

0
Chukwujiobi Canon On

I am interested in knowing how case 2 is working inernally.

Well it is according to the specification of the language. The SingletonTestClass instance handler which getInstance() initializes on the call stack is initialized once and only once and it is given static storage duration.

static SingletonTestClass& getInstance() {
    static SingletonTestClass handler;
    return handler;
}

So it lives through out the lifetime of the program and will only be destructed upon program exit.

Constructed objects with static storage duration are destroyed and functions registered with std::atexit are called as part of a call to std::exit. The call to std::exit is sequenced before the destructions and the registered functions. [Note: Returning from main invokes std::exit (6.9.3.1). —end note] —-ISO/IEC 14882:2020(E) section 6.9.3.4