您的位置:首页 > 编程语言 > C语言/C++

从零开始学C++之模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象

2015-03-05 09:44 991 查看
转:http://blog.csdn.net/jnu_simba/article/details/9398465

一、用模板实现单例模式

前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现:

为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -lpthread

使用的是double-check lock, 指针instance_ 最好声明为volatile,防止优化。

Singleton.h:

C++ Code
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

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

/*************************************************************************

> File Name: Singleton.h

> Author: Simba

> Mail: dameng34@163.com

> Created Time: Wed 02 Apr 2014 01:33:39 AM PDT

************************************************************************/

#ifndef _SINGLETON_H_

#define _SINGLETON_H_

#include <iostream>

#include <stdlib.h>

#include <pthread.h>

#include <unistd.h>

#include <sys/types.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

using namespace std;

template < typename T > class Singleton

{

public:

static T &GetInstance()

{

Init();

return *instance_;

}

private:

static void Init()

{

if (instance_ == 0)

{

pthread_mutex_lock(&g_mutex);

if (instance_ == 0)

{

instance_ = new T;

atexit(Destroy); //程序结束时调用注册的函数

}

pthread_mutex_unlock(&g_mutex);

}

}

static void Destroy()

{

delete instance_;

}

Singleton(const Singleton &other);

Singleton &operator=(const Singleton &other);

Singleton();

~Singleton();

static T * volatile instance_;

static pthread_mutex_t g_mutex;

};

template < typename T >

T * volatile Singleton < T >::instance_ = 0;

template < typename T >

pthread_mutex_t Singleton<T> ::g_mutex = PTHREAD_MUTEX_INITIALIZER;

#endif // _SINGLETON_H_
main.cpp:

C++ Code
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

46

47

48

49

50

51

52

53

54

/*************************************************************************

> File Name: main.cpp

> Author: Simba

> Mail: dameng34@163.com

> Created Time: Wed 02 Apr 2014 01:30:13 AM PDT

************************************************************************/

#include "Singleton.h"

class ApplicationImpl

{

public:

ApplicationImpl()

{

cout << "ApplicationImpl ..." << endl;

}

~ApplicationImpl()

{

cout << "~ApplicationImpl ..." << endl;

}

void Run()

{

cout << "Run ..." << endl;

}

};

typedef Singleton < ApplicationImpl > Application;

void *routine(void *arg)

{

Application::GetInstance().Run();

}

int main(void)

{

Application::GetInstance().Run();

pthread_t tid;

int ret;

if ((ret = pthread_create(&tid, NULL, routine, NULL)) != 0)

{

fprintf(stderr, "pthread create: %s\n", strerror(ret));

exit(EXIT_FAILURE);

}

Application::GetInstance().Run();

pthread_join(tid, NULL);

return 0;

}


即 将Singleton 实现为模板类,将ApplicationImpl 类包装成单例模式类,可以看到构造函数和析构函数都只调用了一次。程序使用一个小技巧,用axexit 函数注册了程序结束时需要调用的函数。

二、模板方式实现动态创建对象

前面的文章曾经使用宏定义的方式实现动态创建对象,现在在 DynBase.h 中用模板类将宏定义替换掉,其他代码不变:

C++ Code
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

//class Register

//{

//public:

// Register(const string &name, CREATE_FUNC func)

// {

// DynObjectFactory::Register(name, func);

// }

//};

//

//#define REGISTER_CLASS(class_name) \

//class class_name##Register { \

//public: \

// static void* NewInstance() \

// { \

// return new class_name; \

// } \

//private: \

// static Register reg_; \

//}; \

//Register class_name##Register::reg_(#class_name, class_name##Register::NewInstance)

template <typename T>

class DelegatingClass

{

public:

DelegatingClass(const string &name)

{

DynObjectFactory::Register(name, &(DelegatingClass::NewInstance));

}

static void *NewInstance()

{

return new T;

}

};

#define REGISTER_CLASS(class_name) DelegatingClass<class_name> class##class_name(#class_name)

即 REGISTER_CLASS(class_name) 宏定义展开会构造一个模板类实例对象,调用3次宏定义即3个模板类实例对象,调用构造函数

DelegatingClass(const string &name),进而调用Register 完成注册,接下去的流程与以前的程序一样,不再赘述。输出如下:



参考:

C++ primer 第四版

Effective C++ 3rd

C++编程规范
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐