赞
踩
在编写sylar服务器时,遇到一种没见过的非常好的单例模式实现,找遍CSDN就只有两篇博客,还没有讲解。只好自己尝试理解。
singleton.h
头文件代码#ifndef __SINGLETON_H__ #define __SINGLETON_H__ /** * @brief 单例模式封装类 * @details T 类型 * X 为了创造多个实例对应的Tag * N 同一个Tag创造多个实例索引 */ template<class T, class X = void, int N = 0> class Singleton { public: static T* GetInstance() { static T v; return &v; } }; /** * @brief 单例模式智能指针封装类 * @details T 类型 * X 为了创造多个实例对应的Tag * N 同一个Tag创造多个实例索引 */ template<class T, class X = void, int N = 0> class SingletonPtr { public: static std::shared_ptr<T> GetInstance() { static std::shared_ptr<T> v(new T); return v; } }; #endif
第一个要说明的点就是模板类型参数class X = void
和 int N = 0
的作用。他们相当于一个索引,能使得 对于同一个类型T
,产生多个实例,产生多个实例后,可以用这两个参数来索引这些实例。但这是和单例模式的思想冲突的。
后来受到群友的启发有点理解了这种写法的应用场景。就是在一些特殊场景,需要用到多个实例,采用这种写法就可以用索引进行区分。
如果有大佬知道这两个参数的其他意义烦请在评论区留言,非常感谢。
这个只要请搞清楚静态局部变量的内存分配和初始化方式即可,参考下面我的另一篇博客。
C++中全局变量,静态变量,静态局部变量 的初始化和内存分配问题
这个单例模式的强大之处在于它具有很高的复用性,sylar服务器中也确实有很多需要用单例模式的类都使用了该模板。
#include<iostream> #include<stdio.h> using namespace std; class X { public: void func() { cout << "XXXXXXXXXXX" << endl; } }; class Y { public: void func() { cout << " YYYYYYYYYY" << endl; } }; template<class T, class X = void, int N = 0> // X:为了创造多个实例对应的 Tag class Singleton // N:同一个 Tag 创造多个实例索引 { public: static T* GetInstance() { static T v; static int x; x++; printf("x = %d\tX: %p\n", x, &x); return &v; } }; int main() { X* x1 = Singleton<X>::GetInstance(); x1->func(); X* x2 = Singleton<X, Y>::GetInstance(); x2->func(); X* x11 = Singleton<X>::GetInstance(); x11->func(); printf("%p\n%p\n%p\n", x1, x2, x11); return 0; }
输出:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。