单例模式
Singletion模式:一种常用的软件设计模式,核心结构只包含一个被称为单例的特殊类。
单例模式下一个类只有一个实例。
特点:1)单例类只能有一个实例
2)单例类必须自己创建自己的唯一实例
3)单例类必须给系统提供这一实例
(2)和(3)的实现是通过提供公有的静态接口函数,由于为静态,可在全局访问到此函数,来创建或获取他本身的静态私有对象。
为什么?
Singletion* Singletion::Instance()
{
if (instance == NULL)
{
instance = new Singletion();
}
return instance;
}
当第一次访问该函数时,会在堆上申请一块内存,让类类型的指针指向这片内存,调用构造函数来创建该对象。
该函数的返回值为类类型的指针,当再次访问此函数,会返回指向这个对象的地址,访问则可通过指针来进行
【1】可行方法一:加同步锁前后两次判断实例是否已经存在
(1)将构造函数设为私有函数(禁止他人再创建实例,可实现单例类只有一个实例)。
(2)一个静态的类类型的指针,当对象创建完成,可通过静态指针在全局访问到该对象。
(3)要满足在多线程环境中能工作,则需要加上同步锁。
(4)加同步锁后,应该看考虑效率问题,如何进行加锁呢?
在实例未创建出来需要进行加锁,来保证只有一个线程创建出实例。实例创建出来之后,不需要执行加锁步骤了。(即实例为空时)
【2】在c#下,利用静态构造函数(该函数确保只调用一次)
(1)为什么?
c#是在调用静态构造函数时初始化静态变量,在初始化静态变量时创建了一个实例。
.NET运行时确保只调用了一次构造函数,即只初始化了一次静态变量,即只创建了一个实例。
(2)存在问题:实例不是在第一次调用属性方法时被创建,而是第一次用到类时就被创建,在使用某些不需要创建实例便可使用的方法(例如在类中添加一静态方法)时,会降低内存的使用效率。
【3】利用私有嵌套类型的特性来实现按需创建实例(解决2中实例创建过早的问题)
有两种模式
(1)懒汉模式 线程不安全 类加载时不进行初始化,适用于访问量小的情况
Singletion* Singletion::instance = NULL;
Singletion::Singletion()
{
cout << "Singletioning" << endl;
}
Singletion* Singletion::Instance()
{
if (instance == NULL)
{
instance = new Singletion();
}
return instance;
}
(2)饿汉式 类加载时便完成了初始化 (线程安全,适用在多线程下,访问量大的情况)
Singletion* Singletion::instance = new Singletion();
Singletion::Singletion()
{
cout << "Singletioning" << endl;
}
Singletion* Singletion::Instance()
{
return instance;
完整代码如下
#ifndef SINGLETION_H
#define SINGLETION_H
#include<iostream>
using namespace std;
class Singletion
{
public:
static Singletion* Instance();//提供一个公有静态的接口函数
private:
Singletion(); //私有的构造函数
static Singletion* instance;//一个静态的类类型的指针
};
#endif
#include"singletion.h"
Singletion* Singletion::instance = NULL;
/*//饿汉式 类加载时便完成了初始化
Singletion* Singletion::instance = new Singletion(); */
Singletion::Singletion()
{
cout << "Singletioning" << endl;
}
Singletion* Singletion::Instance()
{
if (instance == NULL)
{
instance = new Singletion();
}
return instance;
}
int main()
{
Singletion* sgn = Singletion::Instance();
return 0;
}