c++设计模式:单例模式

单例模式

参考github
这个网站也非常生动。

C++实现

  1. 非线程安全(懒汉)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <iostream>
    #include <string>
    #include <thread>
    #include <mutex>
    class Single{
    protected:
    static Single* instance;
    Single(){}

    public:
    static Single* getInstance();
    Single& operator=(const Single&) = delete;
    Single(const Single&) = delete;
    };
    Single* Single::getInstance(){
    if(instance == nullptr){
    instance = new Single();
    }
    return instance;
    }

    void func1(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Single* singleton = Single::getInstance();
    std::cout << "f1 addr:" << singleton << std::endl;
    }

    void func2(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Single* singleton = Single::getInstance();
    std::cout << "f2 addr:" << singleton << std::endl;
    }
    Single* Single::instance = nullptr;
    int main(){
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();

    return 0;
    }
  2. 线程安全懒汉(获得单例的时候加锁)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
class Single{
protected:
static Single* instance;
static std::mutex s_mutex;
Single(){}

public:
static Single* getInstance();
Single& operator=(const Single&) = delete;
Single(const Single&) = delete;
};
Single* Single::getInstance(){
std::unique_lock<std::mutex> lock(s_mutex);
if(instance == nullptr){
instance = new Single();
}
return instance;
}


void func1(){
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
Single* singleton = Single::getInstance();
std::cout << "f1 addr:" << singleton << std::endl;
}

void func2(){
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
Single* singleton = Single::getInstance();
std::cout << "f2 addr:" << singleton << std::endl;
}
std::mutex Single::s_mutex;
Single* Single::instance = nullptr;
int main(){
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();

return 0;
}
  1. 线程安全懒汉(c++11局部静态变量)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <iostream>
    #include <string>
    #include <thread>
    #include <mutex>
    class Single{
    private:
    Single() = default;
    ~Single(){}
    Single(const Single&) = delete;
    Single(Single&&) = delete;
    Single& operator=(const Single&) = delete;
    Single& operator=(Single&&) = delete;
    public:
    static Single* getInstance();
    };
    Single* Single::getInstance(){
    static Single instance {};
    return &instance;
    }

    void func1(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Single* singleton = Single::getInstance();
    std::cout << "f1 addr:" << singleton << std::endl;
    }

    void func2(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Single* singleton = Single::getInstance();
    std::cout << "f2 addr:" << singleton << std::endl;
    }
    int main(){
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();

    return 0;
    }
  2. 线程安全饿汉式(直接显式申请)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #include <iostream>
    #include <string>
    #include <thread>
    #include <mutex>
    class Single{
    protected:
    static Single* instance;
    Single(){}

    public:
    static Single* getInstance();
    Single& operator=(const Single&) = delete;
    Single(const Single&) = delete;
    static void freeSingle();
    };
    Single* Single::getInstance(){
    if(instance == nullptr){
    instance = new Single();
    }
    return instance;
    }
    void Single::freeSingle(){
    delete(instance);
    }

    void func1(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Single* singleton = Single::getInstance();
    std::cout << "f1 addr:" << singleton << std::endl;
    }

    void func2(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Single* singleton = Single::getInstance();
    std::cout << "f2 addr:" << singleton << std::endl;
    }
    Single* Single::instance = new Single();
    int main(){
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();
    Single::freeSingle();
    return 0;
    }
  • 懒汉式是以时间换空间,适应于访问量较小时;推荐使用内部静态变量的懒汉单例,代码量少
  • 饿汉式是以空间换时间,适应于访问量较大时,或者线程比较多的的情况