1

Why when we use singleton in c++ we create a method to construct static object of class but don't use static object? I mean why we do this:

#include <iostream>

struct Singleton {
public:
    static Singleton& instance() {
        static Singleton s;
        return s;
    }
    void getter() {
        std::cout << "asd";
    }

private:
    Singleton() = default;
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
};

int main() {
    Singleton& s = Singleton::instance();
}

but not this:

#include <iostream>

struct Singleton {
public:
    static Singleton s;
    void getter() {
        std::cout << "asd";
    }

private:
    Singleton() = default;
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
};

int main() {
    Singleton::s.getter();
}

I mean why does we need a method to construct static object if we can just create static object and work with it?

6
  • 5
    Both approaches can work, but the first is known as the "Meyers' Singleton" and has the benefit that it guaranties your singleton will be initialized exactly when it is first used. The second version only guaranties that it will be initialized before other global objects and static members defined later in the same source file. If two source files are compiled, you generally cannot control in which order the global objects and static members they define will be initialized relative to each other. Commented Jul 22, 2022 at 2:01
  • @FrançoisAndrieux but the second one doesn't work. Compiler writes undefined reference to Singleton::s Commented Jul 22, 2022 at 2:07
  • 1
    @notamaster You need to define it in global namespace like Singleton Singleton::s;. Commented Jul 22, 2022 at 2:23
  • 1
    @notamaster Because it's a static member variable, it's different with non-static ones. Commented Jul 22, 2022 at 2:59
  • 1
    Note that having singletons in your design may adversely affect the unit testability and maintainability of your code. Consider dependency injection, e.g. inject an interface (abstract base) with getters for the global data you need. After some 30 years of coding/designing I always try to make designs without singletons/globals if possible. Commented Jul 22, 2022 at 7:52

1 Answer 1

1

The short answer is that people do what you are asking about because they want to avoid bugs resulting from global variables being initialized out of order. In particular, suppose that some other global variable made use of the singleton object in its initialization. You'd run the risk that the second object uses the first uninitialized, if the initialization happens in the wrong order. With the function-level static object, you are guaranteed that the object is initialized at the time you use it.

Note you'll need to define s in exactly one translation unit, even while it's declared in every unit (in the header file).

Sign up to request clarification or add additional context in comments.

2 Comments

But I can't use inline in second example because of type of this variable is Singleton and I can't define s in class Singleton
@notamaster Oops, you are right. Sorry about that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.