当前位置:网站首页>Singleton mode

Singleton mode

2022-04-23 20:43:00 baboon_ chen

A class can only create one object ( Or instance ), This design pattern is called singleton pattern .

The basic steps of creating a singleton :

  1. Constructor privatization , Avoid using external constructors to create objects .
  2. Add private static pointer variables (instance), This enables static member functions to access .
  3. Provide static public Interface , Allows the user to obtain a single instance .

One 、 Hungry Chinese style

Class is instantiated when it is defined .

#include <iostream>
using namespace std;

class Singleton {
private:
    //	1、 Declare the constructor as private or protected
    Singleton() {};
    Singleton(const Singleton &) {};
    //	2、 Declare a private static member 
    static Singleton *s_instance;
public:
    // 3、 establish public static Method , Return instance , For external calls .
    static Singleton* GetInstance();
    void fun() {
        cout << "call instance.\n";
    }
};

//	4、 Static member initialization , Internal members can call private functions 
Singleton* Singleton::s_instance = new Singleton();
Singleton* Singleton::GetInstance() {
    return s_instance;
}

int main()
{
    Singleton::GetInstance()->fun();
    return 0;
}

advantage : Thread safety

shortcoming : Delayed loading is not supported


Two 、 Slacker type

Class instances are instantiated the first time they are used .

#include <iostream>
using namespace std;

class Singleton {
private:
    //	1、 Declare the constructor as private or protected
    Singleton() {};
    Singleton(const Singleton &) {};
public:
    //	2、 establish public static Method for external use and returns instance
    static Singleton* GetInstance();
    void fun() {
        cout << "call instance.\n";
    }
};

Singleton* Singleton::GetInstance() {
    // 3、 Declare local static variables , Initialize... On the first call , When the program ends, it will automatically recycle .
    static Singleton instance;
    return &instance;
}

int main()
{
    Singleton::GetInstance()->fun();
    return 0;
}

advantage : Supports delayed loading 、 Thread safety ,《Effective C++》 Recommended approach

shortcoming : If you change the role of multi-threaded locking mode , Frequent call locking 、 Releasing locks creates performance bottlenecks .


3、 ... and 、 Double detection

as long as instance After being created , Call again getInstance() Function will not enter the lock logic . therefore , This implementation solves the problem of low concurrency of lazy type .

#include <iostream>
#include <mutex>
using namespace std;

class Singleton {
private:
    //	1、 Declare the constructor as private or protected
    Singleton() {};
    Singleton(const Singleton &) {};
    //	2、 Must be declared as a static member , Can be accessed by static member functions .
    static Singleton *s_instance;
    static mutex s_mutex;

public:
    // 3、 Create instance return method , For external calls .
    static Singleton* GetInstance();
    void fun() {
        cout << "call instance.\n";
    }
};

// 4、 Static member variables of a class must be initialized ( Allocate memory )
//  Static member variables are simply declared in a class , No definition , So define outside the class , It's actually allocating memory to static member variables 
Singleton* Singleton::s_instance = nullptr;
mutex Singleton::s_mutex;

Singleton* Singleton::GetInstance() {
    if (s_instance == nullptr) {   //  The first inspection 
        lock_guard<mutex> guard(s_mutex);
        if (s_instance == nullptr) {    //  A second check 
            s_instance = new Singleton();
        }
    }
    return s_instance;
}

int main()
{
    Singleton::GetInstance()->fun();
    return 0;
}

advantage : Supports delayed loading 、 Support single instance implementation with high concurrency .

shortcoming : Double check lock , Due to memory read and write reoder Cause insecurity .


Four 、 Example of packing sheet with template

template<typename T>
class Singleton
{
public:
    static T& getInstance() {
        static T value_; // Static local variables 
        return value_;
    }

private:
    Singleton();
    ~Singleton();
    Singleton(const Singleton&); // copy constructor 
    Singleton& operator=(const Singleton&); // = Operator overloading 
};

class A{
public:
    A(){
       a = 1;
    }
    void func(){
        cout << "A.a = " << a << endl;
    }

private:
    int a;
};

int main()
{
    Singleton<A>::getInstance().func();
    return 0;
}

版权声明
本文为[baboon_ chen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210546351073.html