单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 从具体实现角度来说,就是以下三点:一是单例模式的类只提供私有的构造函数,二是类定义中含有一个该类的静态私有对象,三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。
#pragma once #include<iostream> #include<mutex> #include<windows.h> using namespace std; //单例模式 //单线程 //class Singleton //{ //private: // Singleton() //将构造函数私有化 // { // cout<<"Singleton()"<<endl; // } // Singleton(Singleton&); //将拷贝构造私有化 // Singleton operator=(Singleton); //将赋值重载私有化 //public: // static Singleton* get_instance() // { // if(_instance==NULL) // { // _instance=new Singleton(); // } // return _instance; // } // void print() // { // cout<<"创建完成"<<endl; // } //private: // static Singleton* _instance; //}; 初始化静态变量 //Singleton* Singleton::_instance=NULL; //懒汉模式 多线程(加锁) RAII //static mutex mtx; //class Singleton //{ //private: // Singleton() // {} // Singleton(Singleton&); //将拷贝构造私有化 // Singleton operator=(Singleton); //将赋值重载私有化 //public: // static Singleton* get_instance() //之所以判断_instance两次,是因为分配对象很容易,大部分_instance不为空,如果只判断一次的话,\
//当分配好对象了也要加锁,释放锁,效率太低
// { // if(_instance==NULL) //一个线程访问后加锁执行,时间片完被挂起,下一个线程访问进行判断 // { // //RAII 加锁(多线程访问)使用单例模式,抛异常时或语句块保证锁资源最终释放 // lock_guard<mutex> lck(mtx); // if(_instance==NULL) // { // Singleton* tmp=new Singleton(); //new空间分为3个步骤:1.分配空间2.调用构造函数3.赋值,\ // 编译器优化可能将2,3重排 // MemoryBarrier(); //内存栅栏 上下语句执行顺序不可改变 // _instance=tmp; // } // } // // return _instance; // } // void print() // { // cout<<"创建成功"<<endl; // } //private: // static Singleton* _instance; //}; //Singleton* Singleton::_instance=NULL; //饿汉模式(简洁,高效,不用加锁,但是在某些模式下有缺陷) class Singleton { private: Singleton() { cout<<"Singleton"<<endl; } Singleton(Singleton&); //将拷贝构造私有化 Singleton operator=(Singleton); //将赋值重载私有化 public: static Singleton* get_instance() { return _instance; } void print() { cout<<"创建成功"<<endl; } private: static Singleton* _instance; }; Singleton* Singleton::_instance=new Singleton(); #include "singleton.h" void test() { Singleton::get_instance()->print(); } int main() { test(); system("pause"); return 0; }
本文出自 “liveyoung” 博客,转载请与作者联系!