Description:

A class is guaranteed to have only one instance and to provide a global access point to that instance.

Implementation scheme

The private constructor ensures that it is unique, and the public static method instance() provides an interface to access the instance.

Instance () is responsible for lazily instantiating the singleton when first requested. In multithreaded cases, the C++11 standard guarantees that local (local) static variables are initialized only once and are therefore thread-safe.

class Singleton
{
public:
  static Singleton& instance()
  {
    static Singleton *instance = new Singleton();
    return *instance;
  }
private:
  Singleton() {}
};
Copy the code

Provide easier access to instances

Ease of access is one of the main reasons for using singletons, the ability to access instances in different places, at the cost of being able to easily use objects where they are not wanted.

In addition to singletons, several ways to get instances in code

  1. Passed in as a function parameter

The render object function needs to pass in an object representing the graphics device, manage the render state, and pass it to the render function is naturally..

On the other hand, the AI function needs to Log, but the Log is not the core of its concern, so it is strange to pass in the Log as an argument

Many games have a shallow but broad hierarchy of inheritance. For example, the GameObject base class, from which every object in the game inherits, has a large portion of the code in these derived subclasses, meaning that these classes have the same access methods for the same transactions.

Protected: Log& getLog() {return log_; protected: Log& getLog() {return log_; } private: static Log& log_; }; class Enemy : public GameObject { void doSomething() { getLog().write("I can log!" ); }};Copy the code
  1. Objects that are already global

We can reduce the number of global objects by having existing global objects piggyback with needed objects.

As long as the Game is globally visible, other systems can be accessed through the interface.

class Game
{
public:
  static Game& instance() { return instance_; }
  // 设置log_, et. al. ……
  Log&         getLog()         { return *log_; }
  FileSystem&  getFileSystem()  { return *fileSystem_; }
  AudioPlayer& getAudioPlayer() { return *audioPlayer_; }
private:
  static Game instance_;
  Log         *log_;
  FileSystem  *fileSystem_;
  AudioPlayer *audioPlayer_;
};
Copy the code
  1. Obtained from the server locator

Define a class whose goal is to provide global access to objects. This pattern is known as the server locator pattern.