C++完美实现Singleton模式
- 格式:pdf
- 大小:133.95 KB
- 文档页数:10
c++设计模式:单件模式(SingletonPattern)定义:单件模式确保⼀个类只有⼀个实例,并提供⼀个全局访问点实现⼀:#include <iostream>using namespace std;class CSingleton{public:static CSingleton* getInstance();static void cleanInstance();int getValue();void setValue(int iValue);private:int m_iValue;static CSingleton* m_pSingleton;CSingleton();~CSingleton();};CSingleton* CSingleton::m_pSingleton = NULL;CSingleton::CSingleton(){cout << "Constructor" << endl;}CSingleton::~CSingleton(){cout << "Destructor" << endl;}CSingleton* CSingleton::getInstance(){if (NULL == m_pSingleton){m_pSingleton = new CSingleton();}return m_pSingleton;}void CSingleton::cleanInstance(){delete m_pSingleton;}int CSingleton::getValue(){return m_iValue;}void CSingleton::setValue(int iValue){m_iValue = iValue;}int main(){CSingleton* pSingleton1 = CSingleton::getInstance();CSingleton* pSingleton2 = CSingleton::getInstance();pSingleton1->setValue(123);if (pSingleton1->getValue() == pSingleton2->getValue()){cout << "Two objects is the same instance" << endl;}else{cout << "Two objects isn't the same instance" << endl;}CSingleton::cleanInstance();return0;}相信⼤多数的同仁都喜欢使⽤上边这种单件模式的实现⽅法,如果在单线程的情况下,是没有问题的,但如果是多线程,那么就极有可能会返回两个不同的对象,在调⽤CSingleton::getInstance的时候,两个线程如果都同时运⾏完if判断,⽽⼜还没有调⽤到构造函数的话,想象下后果吧。
⽤C++实现单例模式⼏种写法这篇⽂章主要介绍了C++实现单例模式实例详解的相关资料,需要的朋友可以参考下设计模式之单例模式C++实现⼀、经典实现(⾮线程安全)class Singleton{public:static Singleton* getInstance();protected:Singleton(){}private:static Singleton *p;};Singleton* Singleton::p = NULL;Singleton* Singleton::getInstance(){if (NULL == p)p = new Singleton();return p;}⼆、懒汉模式与饿汉模式懒汉:故名思义,不到万不得已就不会去实例化类,也就是说在第⼀次⽤到类实例的时候才会去实例化,所以上边的经典⽅法被归为懒汉实现;饿汉:饿了肯定要饥不择⾷。
所以在单例类定义的时候就进⾏实例化。
特点与选择由于要进⾏线程同步,所以在访问量⽐较⼤,或者可能访问的线程⽐较多时,采⽤饿汉实现,可以实现更好的性能。
这是以空间换时间。
在访问量较⼩时,采⽤懒汉实现。
这是以时间换空间。
线程安全的懒汉模式1.加锁实现线程安全的懒汉模式class Singleton{public:static pthread_mutex_t mutex;static Singleton* getInstance();protected:Singleton(){pthread_mutex_init(&mutex);}private:static Singleton* p;};pthread_mutex_t Singleton::mutex;Singleton* Singleton::p = NULL;Singleton* Singleton::getInstance(){if (NULL == p){pthread_mutex_lock(&mutex);if (NULL == p)p = new Singleton();pthread_mutex_unlock(&mutex);}return p;}class Singleton{public:static pthread_mutex_t mutex;static Singleton* getInstance();protected:Singleton(){pthread_mutex_init(&mutex);}};pthread_mutex_t Singleton::mutex;Singleton* Singleton::getInstance(){pthread_mutex_lock(&mutex);static singleton obj;pthread_mutex_unlock(&mutex);return &obj;}饿汉模式(本⾝就线程安全)class Singleton{public:static Singleton* getInstance();protected:Singleton(){}private:static Singleton* p;};Singleton* Singleton::p = new Singleton; Singleton* Singleton::getInstance(){ return p;}。
单例模式(C++代码实现)1、先来谈谈什么是单例模式这个单例模式说⽩了就⼀个句话:我是皇帝我独苗看看书上的定义:单例模式(Singleton Pattern)Ensure a class has only one instance, and provide a global point of access to it.(确保⼀个类只有⼀个实例,⽽且⾃⾏实例化并向整个系统提供这个实例)使⽤场景:⼀个系统要求⼀个类只有且仅有⼀个对象,如果出现多个对象就会出现不良反应,可以采⽤单例模式要求⽣成唯⼀序列号在整个项⽬需要⼀个共享访问点或共享数据创建⼀个对象需要消耗的资源过多,如需要访问IO和数据库等资源需要⼤量定义静态常量和静态⽅法(如⼯具类)的环境,当然也可以直接定义为static2、实现思路:既然只能有⼀个实例,那我这个类⾥的构造函数就不能被随便调⽤了,那我就把构造函数写成私有的,这样别⼈就不能调⽤了,接下来就该考虑我⾃⼰这个独苗该怎么产⽣了,定义⾥⾯说到⾃⾏实例化,并且提供给整个系统,那我就⽤⼀个static 实例化⼀个实例,然后返回这个static实例。
3、考虑的问题⼀个实例,整个系统使⽤,那线程同步问题就必须要考虑了。
为了解决这个问题:懒汉模式、饿懒汉模式、Meyers Singleton(⽬前最推荐的C++单例写法)4、代码实现//Meyers Singleton(⽬前最推荐的C++单例写法)#include <iostream>using namespace std;class Singleton{public:static Singleton& Instance(){static Singleton theSingleton;return theSingleton;}void doSomeThong();private:Singleton();~Singleton();};Singleton::Singleton(){}Singleton::~Singleton(){}void Singleton::doSomeThong(){cout << "单例类" << endl;cout << "C++最推荐的单例类写法" << endl;}int main(){Singleton::Instance().doSomeThong();return0;}//懒汉模式:顾名思义,是⼀种典型的拖延(lazy)策略。
.NETc#单体模式(Singleton)单体模式(Singleton)是经常为了保证应⽤程序操作某⼀全局对象,让其保持⼀致⽽产⽣的对象,例如对⽂件的读写操作的锁定,数据库操作的时候的事务回滚,还有任务管理器操作,都是⼀单体模式读取的。
创建⼀个单体模式类,必须符合三个条件:1:私有构造函数(防⽌其他对象创建实例);2:⼀个单体类型的私有变量;3:静态全局获取接⼝下⾯我写⼀个类,为了看是不是单体,就加了⼀个计数器,如果是同⼀个类,那么这个类的计数每次调⽤以后就应该⾃动加⼀,⽽不是重新建对象归零:.NET c# 单体模式using System;using System.Threading;public class Singleton{private int ObjCount=0;private Singleton(){Console.WriteLine("创建对象");}private static Singleton objInstance = null;public static Singleton getInstance() {if (objInstance==null) objInstance=new Singleton();return objInstance;}public void ShowCount(){ObjCount++;Console.WriteLine("单个对象被调⽤了{0}次",ObjCount);}};然后我们来测试⼀下:public class ConsoleTest{public static void Main(string[] args){Console.WriteLine("开始执⾏单体模式");for(int i=0;i<5;i++){Singleton.getInstance().ShowCount();}Console.ReadLine();}};我在这个Main⾥⾯执⾏了5次,看看输出的结果:开始执⾏单体模式创建对象单个对象被调⽤了1次单个对象被调⽤了2次单个对象被调⽤了3次单个对象被调⽤了4次单个对象被调⽤了5次在这⾥可以看出,每次都是使⽤的同⼀个对象,实现了单体。
C++ 单件类singleton 模式与示例在写MANET Simulator 时,为了记录trace 文件,我用了一个LogFile 的类,这个类为了使用简便,而不必在每个使用日志的类中都建立一个LogFile对象,最好的办法就是把这个LogFile类设计成Singleton.具体如下:1)--------------------------------------- 头文件:#ifndef _LOG_H_#define _LOG_H_#include <iostream>#include <fstream>class LogFile{private:LogFile();~LogFile();LogFile( const LogFile& ); // Prevent copy-construction.public:static LogFile* instance();private:static LogFile* pObjLog;void CloseFiles();public:// 1 Error log file, record the errors and warnings.static std::ofstream m_ofErrLog;// 2 Running log file, record the running results and hints.static std::ofstream m_ofRunLog;// 3 Forwarding log file, record the forwarding actions.static std::ofstream m_ofForwardLog;// 4 Location log file, record the nodes' moving actions and locations.static std::ofstream m_ofLocLog;// 5 MN's SIR_state log file, record the MN' SIR states.static std::ofstream m_ofSIRLog;// 6 Record the Percolation Probability of all MNs.static std::ofstream m_ofPPLog;};#endif2)--------------------------------------- cpp文件:#include "..\Log\Log.h"std::ofstream LogFile::m_ofErrLog("NS_ErrLog.txt");std::ofstream LogFile::m_ofRunLog("NS_RunLog.txt");std::ofstream LogFile::m_ofForwardLog("NS_ForwardingLog.txt"); std::ofstream LogFile::m_ofLocLog("NS_LocationLog.txt");std::ofstream LogFile::m_ofSIRLog("NS_SIRLog.txt");std::ofstream LogFile::m_ofPPLog( "Trace\\PercoPr.tr", std::ios::app ); LogFile* LogFile::pObjLog = new LogFile();LogFile::LogFile(){}LogFile::~LogFile(){CloseFiles();if ( NULL != pObjLog ){delete pObjLog;pObjLog = NULL;}}LogFile* LogFile::instance(){if ( NULL != pObjLog ){return pObjLog;}return NULL;}void LogFile::CloseFiles(){m_ofErrLog.close();m_ofRunLog.close();m_ofForwardLog.close();m_ofLocLog.close();m_ofSIRLog.close();m_ofPPLog.close();}这样,只要包含了头文件,就可以在其他地方使用静态trace文件记录trace信息了,如: LogFile::instance()->m_ofErrLog << "Error: the simulate time can not be negative.\n";或LogFile::instance()->m_ofRunLog << "\n---- The NS begins running now. -----\n";整理至此,以便备忘。
C++11实现线程安全的单例模式1. 饿汉模式 使⽤饿汉模式实现单例是⼗分简单的,并且有效避免了线程安全问题,因为将该单例对象定义为static变量,程序启动即将其构造完成了。
代码实现:class Singleton {public: static Singleton* GetInstance() { return singleton_; }static void DestreyInstance() { if (singleton_ != NULL) { delete singleton_; }}private: // 防⽌外部构造。
Singleton() = default; // 防⽌拷贝和赋值。
Singleton& operator=(const Singleton&) = delete; Singleton(const Singleton& singleton2) = delete;private: static Singleton* singleton_;};Singleton* Singleton::singleton_ = new Singleton;int main() { Singleton* s1 = Singleton::GetInstance(); std::cout << s1 << std::endl; Singleton* s2 = Singleton::GetInstance(); std::cout << s2 << std::endl; Singleton.DestreyInstance(); return0;}2.懒汉模式 饿汉⽅式不论是否需要使⽤该对象都将其定义出来,可能浪费了内存,或者减慢了程序的启动速度。
所以使⽤懒汉模式进⾏优化,懒汉模式即延迟构造对象,在第⼀次使⽤该对象的时候才进⾏new该对象。
单件模式(Singleton)C++实现意图:保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点。
实⽤性:1.当类只能有⼀个实例⽽且客户可以从⼀个众所周知的访问点访问它。
2.当这个唯⼀的实例应该是通过⼦类可扩展的,并且客户应该⽆需更改代码就能使⽤⼀个扩展的实例时。
效果: 1.只有⼀个实例,可以严格的控制客户怎样以及何时访问。
2.缩⼩名空间,避免了唯⼀实例的全局变量污染名空间。
3.可以控制对象的实例个数。
代码⽰例:这⾥类是⼀个⼈Micla,世界上仅有⼀个Mical,只能产⽣⼀个实例。
#ifndef _SINGLETON_#define _SINGLETON_class Mical{public:~Mical(){}static Mical* GetMical(){if(NULL == _mpMical){_mpMical = new Mical;static Delete Del;}return _mpMical;}private:static Mical* _mpMical;////避免了不同情况实例化类对象Mical(const Mical& another){}Mical& operator = (const Mical& another){}Mical(){}};#endif实现部分:#include <iostream>#include "Singleton.h"using namespace std;Mical* Mical::_mpMical = NULL;int main(){Mical* pMical = Mical::GetMical();delete Mical::GetMical();return0;}⽤Mical* pMical = Mical::GetMical(); 实现了访问Micla 然后我们可以通过pMical访问Mical的各种属性(假设为:⾝⾼,性别等)之后通过delete Mical::GetMical(); 删除对象。
C++经典面试题:设计一个类,该类只能实例化一次,用main函数测试这个类单例是因为一个就足够了,多了浪费比如邮局里的电话簿只有一本,有需要的人拿来看,没有必要每个人要查的时候工作人员就拿一本出来,看完了再回收例。
如下面的类定义:#include <iostream>#include <string>using namespace std;class CSingleton{public:static CSingleton *GetInstance();//静态成员函数,返回CSingleton的指针private:CSingleton(){}; //私有的构造函数static CSingleton * m_pInstance; //静态的私有类指针};CSingleton *CSingleton::m_pInstance=NULL;//类的静态成员指针的初始化CSingleton *CSingleton::GetInstance(){if (m_pInstance==NULL)//评定是否为第一个对象.m_pInstance= new CSingleton(); //生成新对象return m_pInstance; //返回CSingleton对象指针}void main(){CSingleton *p=CSingleton::GetInstance();//通过类调用静态成员函数.cout<<p<<endl;cout<<p->GetInstance()<<endl;//根据GetInstance,这里没有new新的出来.}调试输出结果:003807A8003807A8Press any key to continue它有一个指唯一实例的静态指针m_pInstance,并且是私有的。
它有一个公有的函数,可以获取这个唯一的实例,并在需要的时候创建该实例。
C#单例模式(SingletonPattern)详解(新⼿写博客,主要是对⾃⼰学习的归纳总结。
会对很多⼩细节详解。
)单例模式的定义:确保⼀个类只有⼀个实例,并提供⼀个全局访问点。
⾸先实例⼤家应该都明⽩就是类⽣成对象的过程简单的就是String s=new String(),则s就是个实例。
Q:如何只⽣成⼀个实例?A:1)⾸先必须将构造函数变为私有从⽽防⽌其他类实例化,并且只能有⼀个构造函数。
因为系统会默认⼀个⽆参构造函数,⽽且默认public访问修饰符。
所以必须写⼀个私有⽆参让默认⽆效。
(通常单例模式都是不带形参的)2)在该类中声明⼀个⾃⼰本⾝的静态实例,然后通过静态⽅法返回。
Q:如何提供⼀个全局访问点?A:在类中创建⼀个公共并且静态的属性。
(因为静态⽅法是类中的⼀个成员⽅法,属于整个类,即不⽤创建任何对象也可以直接调⽤。
单例模式是不允许其他类实例的。
)代码:分为两种模式:ZY模式就是延迟加载,设计模式是为了避免⼀些⽆谓的性能开销⽽提出来的,所谓延迟加载就是当在真正需要数据(读取属性值)的时候,才真正执⾏数据加载操作.有效使⽤它可以⼤⼤提⾼系统性能。
2.饿汉模式与LAZY模式相反,加载时会将⾃⼰实例化。
起来最容易的单例模式。
分析代码1:(经典)// 不要⽤这种⽅式public sealed class Singleton{private static Singleton instance=null;//声明⾃⼰本⾝的静态实例private Singleton(){}//私有构造public static Singleton Instance() //提供全局访问点{if (instance==null)//实例不存在则创建{instance = new Singleton();}return instance;}}该代码仅供理解,单例模式的定义。
问题:该⽅法是⾮线程安全的,当有两个线程同时进⼊时,如果instance为null则都会创建实例。
单例模式c实现⼀单例模式介绍单例模式约束了类的实例化,只允许类创建⼀个对象。
在⽤代码实现单例模式之前,先看看单例模式的类结构:特点:1. 类的构造函数外界不可访问.2. 提供了创建对象的接⼝.⼆单例模式C++实现1. 实现⽅法⼀(只作为样例,不推荐使⽤)[cpp]view plaincopy?1. // .h⽂件2. class SimpleSingleton3. {4. public:5. ~SimpleSingleton(){} // 因为外界负责delete,所以须注意析构函数访问权限6. static SimpleSingleton* Instance()7. {8. if(!instance_) // 线程不安全,这⾥需要同步9. instance_ = new SimpleSingleton;10. return instance_;11. }12. protected:13. SimpleSingleton(){}14.15. static SimpleSingleton* instance_;16. };17. // cpp⽂件18. SimpleSingleton* SimpleSingleton::instance_ = 0;该⽅法是简陋的单例模式实现⽅式,缺点是:该类只负责类对象的创建,没有负责销毁,还得程序员负责在合适的时机销毁,所以不推荐使⽤该⽅法。
2 实现⽅法⼆(智能指针⽅式)[cpp]view plaincopy?1. // .h⽂件2. class PtrSingleton3. {4. public:5. ~PtrSingleton(){} // 必须为public, 智能指针负责析构6. static scoped_ptr<PtrSingleton>& Instance()7. {8. if(NULL == instance_.get()) // 线程不安全,这⾥需要同步9. instance_.reset(new PtrSingleton);10. return instance_;11. }12. // other members13. protected:14. PtrSingleton(){}15.16. static scoped_ptr<PtrSingleton> instance_;17. };18.19. // .cpp⽂件20. scoped_ptr<PtrSingleton> PtrSingleton::instance_;该⽅法特点:1) 避免了⼿动析构.2) 值得注意的是实例化接⼝返回类型不是对象指针、值、引⽤,⽽是智能指针.3) 但在实际使⽤中要考虑到多线程环境下的使⽤,Instance接⼝是线程不安全的,需要同步⼀下,本篇重点讲单例模式,代码样例中就不做线程同步了.3 实现⽅法三(简单⽅式)[cpp]view plaincopy?1. // .cpp⽂件2. class Singleton3. {4. public:5. ~Singleton(){}6. static Singleton& Instance(){return instance_;}7. // testing member8.9. protected:10. Singleton(){}11. Singleton(const Singleton&);12. Singleton& operator=(const Singleton&);13.14. private:15. static Singleton instance_;16. };17. // .cpp⽂件18. Singleton Singleton::instance_;这种⽅法实现起来简单,⽤起来⽅便,安全。
C#实现单例模式的多种⽅式什么是单例模式?这⾥我就不做过多的解释了, 毕竟关于Singleton的资料实在是太多太多了。
简单的思路就是, 创建对象单例的动作转移到另外的⾏为上⾯, 利⽤⼀个⾏为去创建对象⾃⾝, 如下:public class Singleton{private Sington() { }private static Singleton _Singleton = null;public static Singleton CreateInstance(){if (_Singleton == null){Console.WriteLine("被创建");_Singleton = new Singleton();}return _Singleton;}}这样写看上去是没有问题, 但是有没有那种可能, 同时两个动作都判断这个对象为空, 那么这个对象就会被创建2次?是的, 多线程中, 这样是⽆法保证单例。
就像这样, 同时创建多个线程去创建这个对象实例的时候, 会被多次创建, 这个时候, 对代码改进⼀下。
public class Singleton{ private Sington() { }private static Singleton _Singleton = null;private static object Singleton_Lock = new object(); //锁同步public static Singleton CreateInstance(){lock (Singleton_Lock){ Console.WriteLine("路过");if (_Singleton == null){ Console.WriteLine("被创建");_Singleton = new Singleton();}}return _Singleton;}}调试代码:TaskFactory taskFactory = new TaskFactory();List<Task> taskList = new List<Task>();for (int i = 0; i < 5; i++){taskList.Add(taskFactory.StartNew(() =>{Singleton singleton = Singleton.CreateInstance();}));}结果:上⾯, 我们创建了多个线程,同时去创建这个对象的实例, 在第⼆次,对象命名已经被创建了, 尽管只创建了⼀次满⾜了我们的需求, 但是我们已知对象被创建了, 还需要进来做不必要的动作吗?我们都知道, 同步锁为了达到预期的效果, 也是损耗了性能的, 那么下⾯的输出, 很显然是没必要的动作, 所以我们优化⼀下。
c++实现单例模式的三种⽅案第⼀种:单线程(懒汉)第⼆种:多线程(互斥量实现锁+懒汉)第三种:多线程(const static+饿汉)(还要继续了解)//单线程解法//这种解法在多线程的情况下,可能创建多个实例。
class Singleton1{private:static Singleton1* m_pInstance1;//需要的时候才创建,懒汉//利⽤static关键字的特性,不属于任何类,整个类只有⼀个Singleton1();public:static Singleton1* GetInstance1();static void DestroyInstance1();};Singleton1::Singleton1(){cout << "创建单例" << endl;}Singleton1* Singleton1::GetInstance1(){return m_pInstance1;}void Singleton1::DestroyInstance1(){if (m_pInstance1 != nullptr){delete m_pInstance1;m_pInstance1 = nullptr;}}//初始化⼀个对象Singleton1* Singleton1::m_pInstance1 = new Singleton1();//单线程下多次获取实例void test1(){Singleton1* singletoObj1 = Singleton1::GetInstance1();cout << singletoObj1 << endl;Singleton1* singletoObj2 = Singleton1::GetInstance1();cout << singletoObj2 << endl;//上⾯的两个对象会指向同⼀个地址Singleton1::DestroyInstance1();}//多线程+加锁(互斥量)class Singleton2{private:Singleton2();static Singleton2* m_pInstance2;static mutex m_mutex;//互斥量public:static Singleton2* GetInstance2();static void DestroyInstance2();};Singleton2::Singleton2(){cout << "创建单例2" << endl;}Singleton2* Singleton2::GetInstance2(){if (m_pInstance2 == nullptr){cout << "加锁中" << endl;m_mutex.lock();if (m_pInstance2 == nullptr){m_pInstance2 = new Singleton2();}cout << "解锁中" << endl;m_mutex.unlock();}return m_pInstance2;}void Singleton2::DestroyInstance2(){if (m_pInstance2 != nullptr){delete m_pInstance2;m_pInstance2 = nullptr;}}//静态成员变量的定义Singleton2* Singleton2::m_pInstance2 = nullptr;//懒汉式的写法mutex Singleton2::m_mutex;//常见⼀个实例对象,给下⾯的多线程调⽤void print_singleton_instance(){Singleton2* singletonObj2 = Singleton2::GetInstance2();cout << "新的⼀个实例对象" << singletonObj2 << endl;}void test2(){vector<thread> threads;for (int i = 0; i < 10; i++){//⼗个线程都指向同⼀个静态变量的地址threads.push_back(thread(print_singleton_instance));}for (auto& thr : threads){thr.join();}}//⽅案三:使⽤const特性,来替换⽅案⼆的加锁操作class Singleton3{private:Singleton3(){}static const Singleton3* m_pInstance3;public:static Singleton3* GetInstance3();static void DestroyInstance3();};Singleton3* Singleton3::GetInstance3(){//这个函数的返回值如果变化曾const static属性,就不⽤进⾏const_castreturn const_cast<Singleton3*> (m_pInstance3);}void Singleton3::DestroyInstance3(){if (m_pInstance3 != nullptr){delete m_pInstance3;m_pInstance3 = nullptr;}}//静态成员变量的定义const Singleton3* Singleton3::m_pInstance3 = new Singleton3();//饿汉式的写法//常见⼀个实例对象,给下⾯的多线程调⽤void print_singleton_instance3(){Singleton3* singletonObj3 = Singleton3::GetInstance3();cout << "新的⼀个实例对象" << singletonObj3 << endl;}void test3(){vector<thread> threads;for (int i = 0; i < 10; i++){//⼗个线程都指向同⼀个静态变量的地址threads.push_back(thread(print_singleton_instance3));}for (auto& thr : threads){thr.join();}}。
c++11改进设计模式Singleton模式关于学习《深⼊应⽤c++11》的代码笔记:c++11之前是这么实现的template<typename T>class Singleton{public:static T* Instance(){if (m_pInstance == nullptr)m_pInstance = new T();return m_pInstance;}template<typename T0>static T* Instance(T0 arg0){if (m_pInstance == nullptr)m_pInstance = new T(arg0);return m_pInstance;}template<typename T0,typename T1>static T* Instance(T0 arg0, T1 arg1){if (m_pInstance == nullptr)m_pInstance = new T(arg0, arg1);return m_pInstance;}template<typename T0, typename T1,typename T2>static T* Instance(T0 arg0, T1 arg1,T2 arg2){if (m_pInstance == nullptr)m_pInstance = new T(arg0, arg1,arg2);return m_pInstance;}template<typename T0, typename T1, typename T2,typename T3>static T* Instance(T0 arg0, T1 arg1, T2 arg2,T3 arg3){if (m_pInstance == nullptr)m_pInstance = new T(arg0, arg1, arg2,arg3);return m_pInstance;}template<typename T0, typename T1, typename T2, typename T3,typename T4>static T* Instance(T0 arg0, T1 arg1, T2 arg2, T3 arg3,T4 arg4){if (m_pInstance == nullptr)m_pInstance = new T(arg0, arg1, arg2, arg3,arg4);return m_pInstance;}template<typename T0, typename T1, typename T2, typename T3, typename T4,typename T5>static T* Instance(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,T5 arg5){if (m_pInstance == nullptr)m_pInstance = new T(arg0, arg1, arg2, arg3, arg4,arg5);return m_pInstance;}static T* GetInstance(){if (m_pInstance == nullptr)throw std::logic_error("the instance is not init,please init the instance first");return m_pInstance;}static void DestroyInstance(){delete m_pInstance;m_pInstance = nullptr;}private:Singleton(void);virtual ~Singleton(void);Singleton(const Singleton&);Singleton& operator = (const Singleton);static T* m_pInstance;};template<class T> T* Singleton<T>::m_pInstance = nullptr;//============================================struct A{A(){}};struct B{B(int x){}};struct C{C(int x, double y){}};int _tmain(int argc, _TCHAR* argv[]){Singleton<A>::Instance();Singleton<A>::Instance();Singleton<B>::Instance(1);Singleton<C>::Instance(1,3.14);Singleton<A>::DestroyInstance();Singleton<B>::DestroyInstance();Singleton<C>::DestroyInstance();return 0;} c++11之后可以简略⼀点,使⽤了可变模板参数template<typename T>class Singleton{public:template <typename... Args>static T* Instance(Args&&... args){if (m_pInstance == nullptr)m_pInstance = new T(std::forward<Args>(args)...);return m_pInstance;}static T* GetInstance(){if (m_pInstance == nullptr)throw std::logic_error("the instance is not init,please initialize the instance first"); return m_pInstance;}static void DestroyInstance(){delete m_pInstance;m_pInstance = nullptr;}private:Singleton(void);virtual ~Singleton(void);Singleton(const Singleton&);Singleton& operator=(const Singleton&);private:static T* m_pInstance;};template<class T>T* Singleton<T>::m_pInstance = nullptr;#include <iostream>#include <string>using namespace std;struct A{A(const string&){ cout << "lvalue" << endl; }A(string&&x){ cout << "rvalue" << endl; }};struct B{B(const string&){ cout << "lvalue" << endl; }B(string&& x){ cout << "rvalue" << endl; }};struct C{C(int x, double y){}void Fun(){ cout << "Test" << endl; }};int _tmain(int argc, _TCHAR* argv[]){string str = "bb";Singleton<A>::Instance(str);Singleton<B>::Instance(std::move(str)); Singleton<C>::Instance(1,3.14);Singleton<C>::GetInstance()->Fun(); Singleton<A>::DestroyInstance();Singleton<B>::DestroyInstance();Singleton<C>::DestroyInstance();return 0;}。
C++实现单例模式的⽅法⽬录饿汉模式懒汉模式锁 + 智能指针局部静态变量总结饿汉模式类实例化就会占⽤内存,浪费资源,效率⾼,不存在线程安全问题。
class Singleton{Singleton() { }static Singleton* m_instance_ptr;public:static Singleton* get_instance() {return m_instance_ptr;}};Singleton* Singleton::m_instance_ptr = new Singleton();int main(){Singleton* instance1 = Singleton::get_instance();Singleton* instance2 = Singleton::get_instance();return 0;}懒汉模式延迟加载,节省资源,效率低,存在线程安全问题。
class Singleton {Singleton() { }static Singleton* m_instance_ptr;public:static Singleton* get_instance() {if(m_instance_ptr == nullptr)m_instance_ptr = new Singleton();return m_instance_ptr;}};Singleton* Singleton::m_instance_ptr = nullptr;int main(){Singleton* instance1 = Singleton::get_instance();Singleton* instance2 = Singleton::get_instance();return 0;}锁 + 智能指针线程安全(锁)+ 内存回收(智能指针)#include <iostream>#include <memory>#include <mutex>class Singleton {public:typedef std::shared_ptr<Singleton> Ptr;static Ptr get_instance() {if(m_instance_ptr == nullptr) {std::lock_guard<std::mutex> lk(m_mutex);if(m_instance_ptr == nullptr)m_instance_ptr = std::shared_ptr<Singleton>(new Singleton);}return m_instance_ptr;}private:Singleton() {}static Ptr m_instance_ptr;static std::mutex m_mutex;};Singleton::Ptr Singleton::m_instance_ptr = nullptr;std::mutex Singleton::m_mutex;int main(){Singleton::Ptr instance1 = Singleton::get_instance();Singleton::Ptr instance2 = Singleton::get_instance();return 0;}局部静态变量class Singleton {public:Singleton(const Singleton&)=delete;static Singleton& get_instance() {static Singleton instance;return instance;}private:Singleton() {}};int main() {Singleton& instance1 = Singleton::get_instance();Singleton& instance2 = Singleton::get_instance();return 0;}总结本篇⽂章就到这⾥了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!。
C#实现单件模式的三种常⽤⽅法本⽂实例讲述了C#实现单件模式的三种常⽤⽅法。
分享给⼤家供⼤家参考。
具体分析如下:单件模式是⼀种设计模式,即保持同时只能创建⼀个实例,下⾯列出了C#实现单件模式的三种⽅法⽅法1public sealed Class Singleton{private static ReadOnly Singleton instance = new Singleton();private Singleton(){}public static Singleton Instance{get{return instance;}}}⽅法2public sealed Class ClassicSingleton{private static ClassicSingleton instance;private static object SyncRoot = new Object ();private ClassicSingleton(){}public static ClassicSingleton Instance{get{if(instance == null){lock (SyncRoot){if(instance == null){instance = new ClassicSingleton ();}}}return instance;}}}⽅法3public Class Singleton{private static Singleton instance;// Added a static mutex for synchronising use of instance.private static System.Threading.Mutex mutex;private Singleton(){}static Singleton (){instance = new Singleton();mutex = new System.Threading.Mutex();}public static Singleton Acquire(){mutex.WaitOne ();return instance;}// Each call to Acquire () requires a call to Release()public static void Release(){mutex.ReleaseMutex();}}希望本⽂所述对⼤家的C#程序设计有所帮助。