单例模式:
在一些特定的情况下我们需要一个类只创建一个对象,比如,Windows中的文件管理器,
在多线程多进程访问文件管理器并进行插入删除操作时,如果不能对同一个接口进行操作,
那么势必造成文件系统的混乱。
懒汉模式:
一, 静态指针成员
class Singleton
{
private:
Singleton(){};
virtual ~Singleton(){};
public:
static Singleton* Instance();
private:
static Singleton* _instance;
};
Singleton* Singleton::_instance=NULL; //静态成员要定义在类外
Singleton* Singleton::Instance()
{
if (_instance == NULL)
{
_instance = new Singleton;
}
return _instance;
}
int main()
{
Singleton* a1 = Singleton::Instance();
Singleton* a2 = Singleton::Instance();
cout << a1 << endl;
cout << a2 << endl; //发现结果相同,所以单例成立
return 0;
}
构造单例对象的时机:在调用 Instance 函数时。
对象的位置:堆上
对象资源释放:没有释放
线程安全:不安全。当A线程执行完 if (_instance == NULL) 后,切换到B线程,B线程创建对象完毕,返回A线程,则会再次创建对象,代替B线程创建的对象,那么B线程创建的对象就会内存泄漏。
饿汉模式
二,静态指针成员
class Singleton
{
public:
static Singleton* Instance();
private:
Singleton();
virtual ~Singleton();
Singleton(const Singleton&){};
Singleton& operator=(const Singleton&){};
private:
class CGarbo
{
public:
~CGarbo()
{
if (Singleton::_instance != NULL)
{
cout << "开始析构资源" << endl;
delete _instance;
}
}
};
static Singleton* _instance;
static CGarbo cGarbo;
};
Singleton* Singleton::Instance()
{
return _instance;
}
Singleton::Singleton()
{
cout << "构造函数" << endl;
}
Singleton::~Singleton()
{
cout << "对象析构函数" << endl;
}
Singleton* Singleton::_instance = new Singleton;
Singleton::CGarbo Singleton::cGarbo;
int main()
{
Singleton* a1 = Singleton::Instance();
Singleton* a2 = Singleton::Instance();
cout << a1 << endl;
cout << a2 << endl;
return 0;
}
对象构造的时机:在程序初始化时
对象的位置:堆
对象资源的释放:在Singleton类中定义CGarbor类,并且定义一个静态CGarbo类对象cGarbo,在CGarbor类的析构函数中释放 堆上的资源,由于程序在结束时会自动释放静态成员cGarbo,执行析构函数,来释放堆上的资源。
线程安全:安全 ,因为对象在程序初始化时创建,不存在线程竞争。
分析对比:相比较于第一种方法,第二种方法解决了线程安全和资源释放,但是资源释放的方法太复杂。既然静态成员在程序结 束时会自动释放,那么就可以直接将单例对象初始化为静态对象。
三,静态成员对象
class Singleton
{
public:
static Singleton* Instance()
{
return &singleton;
}
private:
Singleton(){};
virtual ~Singleton(){};
Singleton(const Singleton&){};
Singleton& operator=(const Singleton&){};
static Singleton singleton;
};
Singleton Singleton::singleton;
单例对象构造时机:初始化时构造
对象位置:静态区
资源释放:静态变量,程序结束自动释放
线程安全:安全