单例模式:
从名字上看,表示只能创建唯一一个实例化对象的模式,可细分为饿汉式和懒汉式两种单例模式;
创建步骤:
1.将构造函数访问权限设置成 private 或者 protected ,从而不允许类的外部创建对象,保证对象数目只有一个,进而保障只有一个实例化对象;
2.用一个静态成员指针指向创建的对象;
3.提供一个静态成员函数,用来获取这个对象的首地址;
饿汉式:在单例定义的时候就初始化;
#include <iostream>
using namespace std;
class Hungry
{
public:
//创建一个成员函数获取对象的地址
static Hungry *get_instance()
{
return h;
}
//释放对象资源
static void release_instance()
{
if(h != NULL)
{
delete h;
h = NULL;
}
}
private:
//将构造函数和析构函数设定为私有权限
Hungry() { ; }
~Hungry() { ; }
//定义一个类的静态指针成员
static Hungry *h;
};
//饿汉式的典型特征,定义时实例化唯一对象
Hungry *Hungry::h = new Hungry;
int main(int argc, const char *argv[])
{
cout << Hungry::get_instance() << endl;
Hungry::release_instance();
return 0;
}
懒汉式:在第一次用到类实例的时候才会去实例化;
#include <iostream>
#include <pthread.h>
using namespace std;
class Lazy
{
public:
//创建一个成员函数获取对象的地址
static Lazy *get_instance()
{
if(h != NULL)
return h;
pthread_mutex_lock(&lock);
if(h == NULL) //避免再次创建
{
h = new Lazy;
}
pthread_mutex_unlock(&lock);
return h;
}
//释放对象资源
static void release_instance()
{
if(h != NULL)
{
delete h;
h = NULL;
}
}
private:
//将构造函数和析构函数设定为私有权限
Lazy() { ; }
~Lazy() { ; }
//定义一个类的静态指针成员
static Lazy *h;
static pthread_mutex_t lock;
};
//懒汉式的典型特征,定义时不初始化对象
Lazy *Lazy::h = NULL;
//为了解决多线程的单例创建失效,加一把互斥锁保证对象唯一性
pthread_mutex_t Lazy::lock = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, const char *argv[])
{
cout << Lazy::get_instance() << endl;
Lazy::release_instance();
return 0;
}
总结:
饿汉式:1. 不用担心多线程的问题,能够保证对象的唯一性;2. 有点浪费内存资源,由于是静态的成员变量,程序执行时就会创建,此时该对象比一定用得着;3. 中途对象内存一旦被释放,就无法再次创建,接下来的所有动作都会失效;
懒汉式:1. 节约内存资源,需要用到的时候创建,不需要则不创建或直接释放;2.中途若被释放,可以再次创建,不影响后续代码的执行;3. 当有多个线程,会重复创建,需要添加互斥锁来避免;