单例模式

定义宏删除一些构造函数

1
2
3
4
5
6
7
8
9
10
11
#define DISABLE_COPY(Class) \
Class(const Class &) = delete; \
Class &operator=(const Class &) = delete;

#define DISABLE_MOVE(Class) \
Class(Class &&) = delete; \
Class &operator=(Class &&) = delete;

#define DISABLE_COPY_MOVE(Class) \
DISABLE_COPY(Class) \
DISABLE_MOVE(Class)

懒汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace Lazy {

class Singleton
{
Singleton() { std::cout << "Lazy Singleton" << std::endl; }
~Singleton() { std::cout << "Lazy ~Singleton" << std::endl; }

DISABLE_COPY_MOVE(Singleton)

public:
static Singleton &instance()
{
static Singleton s; // C++11 thread safe
return s;
}
};

} // namespace Lazy

饿汉式

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
namespace Hungry {

class Singleton
{
Singleton() { std::cout << "Hungry Singleton" << std::endl; }
//~Singleton() { std::cout << "Hungry ~Singleton" << std::endl; }

DISABLE_COPY_MOVE(Singleton)

static std::unique_ptr<Singleton> s_singleton_ptr;
static std::mutex s_mutex;

public:
~Singleton() { std::cout << "Hungry ~Singleton" << std::endl; }

// 第一种:依赖锁的线程安全方式;
static Singleton &instance()
{
std::unique_lock locker(s_mutex);
if (!s_singleton_ptr) {
s_singleton_ptr.reset(new Singleton);
}
return *s_singleton_ptr;
}

// 第二种:依赖于std::call_once的线程安全方式;
static Singleton &instance()
{
static std::once_flag flag;
std::call_once(flag, []() {
if (!s_singleton_ptr) {
s_singleton_ptr.reset(new Singleton);
}
});
return *s_singleton_ptr;
}
};

// 第三种:依赖于程序启动时的线程安全方式;
std::unique_ptr<Singleton> Singleton::s_singleton_ptr(new Singleton);
std::mutex Singleton::s_mutex;

} // namespace Hungry

模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace LazyTemplate {

template<typename T>
class Singleton
{
Singleton() = delete;
~Singleton() = delete;

DISABLE_COPY_MOVE(Singleton)

public:
static T &instance()
{
static T t; // C++11 thread safe
return t;
}
};

} // namespace LazyTemplate

测试

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
class Test
{
public:
Test() { std::cout << "Test" << std::endl; }
~Test() { std::cout << "~Test" << std::endl; }

void doSomeThing() { std::cout << "doSomeThing" << std::endl; }
};

int main(int argc, char *argv[])
{
Lazy::Singleton::instance();
Lazy::Singleton::instance();

Hungry::Singleton::instance();
Hungry::Singleton::instance();

LazyTemplate::Singleton<Test>::instance().doSomeThing();
LazyTemplate::Singleton<Test>::instance().doSomeThing();

SingletonManager::instance();
SingletonManager::instance();

return 0;
}

结果

1
2
3
4
5
6
7
8
9
10
11
12
Lazy Singleton
Hungry Singleton
Test
doSomeThing
doSomeThing
Singleton1
Singleton2
~Singleton2
~Singleton1
~Test
Lazy ~Singleton
Hungry ~Singleton

建议

假如程序内部有多个单例类,不妨写一个单例管理类,统一管理,也可以控制这些单例的生命周期,类似如下代码:

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
class SingletonManager
{
SingletonManager()
: m_s1_ptr(new Singleton1)
, m_s2_ptr(new Singleton2)
{}
~SingletonManager() {}

DISABLE_COPY_MOVE(SingletonManager)

std::mutex m_mutex;

std::unique_ptr<Singleton1> m_s1_ptr;
std::unique_ptr<Singleton2> m_s2_ptr;

public:
static SingletonManager &instance()
{
static SingletonManager s; // C++11 thread safe
return s;
}

Singleton1 &singleton1()
{
std::unique_lock locker(m_mutex);
return *m_s1_ptr;
}

Singleton2 &singleton2()
{
std::unique_lock locker(m_mutex);
return *m_s2_ptr;
}
};

Singleton源码