基于模板的单例模式
在用C++实现一个单例模式里,发现在调试程序的时候获取到的不是同一个实例,原来代码如下:
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
| #ifndef SINGELTON_H #define SINGELTON_H #include <iostream> #include <mutex> using namespace std; mutex mtx; class Lock { private: mutex *mtx; public: explicit Lock(mutex *mtx) :mtx(mtx) { this->mtx->lock(); } ~Lock() { this->mtx->unlock(); } };
|
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
| template<typename Type> class Singelton { private: Singelton(){ } public: static Type *instance; static Type &me() { if (instance == NULL) { Lock lock(&mtx); if (instance == NULL) { instance = new Type(); } } return *instance; } }; template<typename Type> Type *Singelton<Type>::instance = NULL; #endif
|
测试程序如下:
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
| #include <iostream> #include <string> #include <vector> #include <thread> #include "Singelton.h" using namespace std; class User { private: string name; public: User(string name = "Init"):name(name) { } string getName() { return name; } void setName(string name) { this->name = name; } }; void testSingelton() { User user1 = Singelton<User>::me(); cout << &user1 << endl; User user2 = Singelton<User>::me(); cout << &user1 << endl; } int main() { vector<thread> threads; const size_t total = 3; for (size_t i = 0; i < total; i++) { threads.push_back(thread(testSingelton)); } for (size_t i = 0; i < threads.size(); i++) { threads[i].join(); } }
|
输出结果:
1 2 3 4 5 6
| 0098F484 00DDF81C 006DCC70 004F7A9C 0010F3F0 00CCF853
|
明显得到的不是同一个对象
查看代码发现原来少了一个引用符号,这样的话User
将会调用复制构造函数得到两个新的对象给user1
和user2
修改为:
1 2 3 4 5 6 7 8
| void testSingelton() { User &user1 = Singelton<User>::me(); cout << &user1 << endl; User &user2 = Singelton<User>::me(); cout << &user2 << endl; }
|
这时候打印的是同一个对象了
1 2 3 4 5 6
| 00626118 00626118 00626118 00626118 00626118 00626118
|
也可以返回指针的方式,这样将不容易出错。