本文整理自网络,后续将不断充实,也许等我变牛了能写出更好的吧,推荐这篇文章,感觉很牛。

# 单例模式

设计模式之一
这种设计模式属于创建型模式,它提供了一种创建对象的最佳方式
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方法,可以直接访问,不需要实例化该类的对象。

# 注意:

  1. 单例类只能有一个实例。
  2. 单例类必须自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

# 实现方式

# 1. 懒汉模式,线程不安全

懒汉模式 (Lazy-Initialization) 直到使用时才会实例化对象,即调用 Instance () 方法时才会 new 一个单例的对象,如果不被调用就不会占用内存。这种模式单线程没有问题,但多线程时就会出现不可靠的情况。(以时间换空间)

#include <iostream>
using namespace std;

class Singleton {
public:
static Singleton *getInstance() {
if(NULL == _pInstance) {
_pInstance = new Singleton();
}
return _pInstance;
}
static void destory() {
if(_pInstance) {
delete _pInstance;
}
}
private:
Singleton() {
cout << "构造函数:Singleton()" << endl;
}
~Singleton() {
cout << "析构函数:~Singleton()" << endl;
}
Singleton(const Singleton &signal);
const Singleton &operator = (const Singleton & signal);
static Singleton *_pInstance;
};

Singleton * Singleton::_pInstance = nullptr;

int main() {
Singleton *p1 = Singleton::getInstance();
Singleton *p2 = Singleton::getInstance();
cout << "&p1 = " << p1 << endl;
cout << "&p2 = " << p2 << endl;
Singleton:destory();
return 0;
}

# 2. 懒汉模式,加锁

#include <iostream>
#include <memory>
#include <mutex>
using namespace std;
class Singleton {
public:
typedef std::shared_ptr<Singleton> Ptr;
~Singleton() {
cout << "析构函数:~Singleton()" << endl;
}
static Ptr getInstance() {
if(_instance == nullptr) {
std::lock_guard<std::mutex> lk(_mutex);
_instance = std::shared_ptr<Singleton>(new Singleton);
}
return _instance;
}
private:
Singleton();
Singleton(const Singleton &sigle);
const Singleton &operator = (const Singleton &sigle);
static Ptr _instance;
static std::mutex _mutex;
};

Singleton::Ptr Singleton::_instance = nullptr;
std::mutex Singleton::_mutex;
Singleton::Singleton::Singleton() {
coout << "构造函数:Singleton()" << endl;
}

int main() {
Singleton::Ptr p1 = Singleton::getInstance();
Singleton::Ptr p2 = Singleton::getInstance();
cout << "&p1 = " << p1 << endl;
cout << "&p2 = " << p2 << endl;
return 0;
}

# 3. 懒汉模式,magic static

#include <iostream>
using namespace std;
class Singleton {
public:
static Singleton& get_instance() {
static Singleton instance;
return instance;
}
private:
Singleton() {
std:cout << "构造函数:Singleton()" << std::endl;
}
~Singleton() {
std:cout << "析构函数:~Singleton()" << std::endl;
}
};

int main(int argc, char *argv[]) {
Singleton& p1 = Singleton::getInstance();
Singleton& p2 = Singleton::getInstance();
cout << "&p1 = " << p1 << endl;
cout << "&p2 = " << p2 << endl;
return 0;
}

# 4. 饿汉模式

加载时就实例化对象(以空间换时间)

#include <iostream>
#include <process.h>
#include <windows.h>
using namespace std;
class Singelton{
private:
Singelton(){
m_count ++;
printf("Singelton begin\n");
Sleep(1000); // 加sleep为了放大效果
printf("Singelton end\n");
}
static Singelton *single;//定义一个唯一指向实例的指针,并且是私有的
public:
static Singelton *GetSingelton();//定义一个公有函数,可以获取这个唯一实例
static void print();
static int m_count;
};
// 饿汉模式的关键:定义即实例化
Singelton *Singelton::single = new Singelton;
int Singelton::m_count = 0;
Singelton *Singelton::GetSingelton(){
// 不再需要进行实例化
//if(single == nullptr){
// single = new Singelton;
//}
return single;
}
void Singelton::print(){
cout<<m_count<<endl;
}
int main()
{
cout << "we get the instance" << endl;
singleton* a1 = singleton::getinstance();
singleton* a2 = singleton::getinstance();
singleton* a3 = singleton::getinstance();
cout << "we destroy the instance" << endl;
system("pause");
return 0;
}