0

I'm looking at two implementations of the Singleton design pattern.

I wanted to know how the second one works, in particular:

  1. Why has the author chosen to return DB as a reference.

  2. Why does the static class object DB in getDatabaseConnection() not need to be defined outside of the SingleDatabase class as such:

SingletonDatabase& SingletonDatabase::DB;
  1. Does a static class object, like a static variable, only get created once (and is shared amongst all objects of the same class)?

Implementation

class SingletonDatabase {
    private:
        SingletonDatabase() {
            std::cout << "Initializing database" << std::endl;
            instanceCount++; // Used in testing later on.
        }

    public:
        SingletonDatabase(const SingletonDatabase&) = delete;
        SingletonDatabase& operator=(const SingletonDatabase&) = delete;
        static SingletonDatabase& getDatabaseConnection() {
            static SingletonDatabase DB;
            return DB;
        }
        static int instanceCount;
};

int SingletonDatabase::instanceCount = 0;

I'm used to seeing the implementation with a static pointer, which the author mentioned is not thread safe. He prefers this method.

Thanks!

mrflash818
  • 930
  • 13
  • 24

2 Answers2

2
  1. Why has the author chosen to return DB as a reference.

Instead of a reference, a pointer could have been used as well. The reference expresses better that the pointee is granted to exist. (Return by value instead would have corrupted the concept.)

  1. Why does the static class object DB in getDatabaseConnection() not need to be defined outside of the SingleDatabase class as such:

SingletonDatabase& SingletonDatabase::DB;

It's not a member variable but a static variable with a local scope but the life-time of a static → granted to exist from first access until end of process.

SO: What is the lifetime of a static variable in a C++ function? (a little bit aged but still correct)

This would've been worked the same way in a plain function. That the surrounding function is a (static member function) is not that relevant concerning this.

  1. Does a static class object, like a static variable, only get created once (and is shared amongst all objects of the same class)?

Yes.

To be correct, it's shared between any caller of this function.


Btw. this is known as Meyers Singleton:

FleCSI: Meyer’s SingletonSO: C++ Singleton design pattern

SO: Is Meyers' implementation of the Singleton pattern thread safe?

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • Shouldn't we do the `=delete` for the move constructors as well? – TonySalimi Oct 17 '19 at 15:49
  • 1
    @Gupta I assumed that `delete`ing the copy constructor deletes the implicit move constructor as well. Uncertain, whether [Implicitly-declared move constructor](https://en.cppreference.com/w/cpp/language/move_constructor#Implicitly-declared_move_constructor) really proves me right, I googled and found [SO: If I delete the copy constructor, do I get no implicit move constructor?](https://stackoverflow.com/a/26803634/7478597). It seems, my assumption is valid. – Scheff's Cat Oct 17 '19 at 17:25
0

To complete @Scheff's points:

I'm used to seeing the implementation with a static pointer, which the author mentioned is not thread safe. He prefers this method.

As this Q/A shows, implementing the singleton pattern with pointers is not thread-safe.

TonySalimi
  • 8,257
  • 4
  • 33
  • 62
  • That's not what I asked. I asked three questions, the third of which has been answered. –  Oct 17 '19 at 16:24