单例模式
来源:互联网 发布:清华经济管理学院知乎 编辑:程序博客网 时间:2024/06/02 01:21
单例模式:
仅从字面的理解,就是只有一个(单个)实例,在代码中的实现也是很简单的:
我们先判断一下这个实例(可能是对象,也可能是变量)是否为空。如果是空值的话,我们就去为他开辟一块内存空间;否则,就直接把这个内存空间返回出去就行了!
可是,为什么要这么做呢?
想一下,比如你在游戏中点击了某个NPC,就会弹出一个npc的对话框(我们先忽略这是个什么样的NPC)如果你有点击了这个npc又出现了一个同样的对话框,这个结果肯定会很糟糕的!或者说没有第二次出现那个对话框,可是程序又因为这失误的代码而为你开辟了第二块内存!这样,新的内存地址覆盖了旧的内存地址,一些数据上的交互要实时更新的东西就会闲的乱七八糟的。也是因为这个原因,刚开辟的内存会一直被占用而没被释放;
像下面的代码:
class Dialog
{
public:
void print()
{
//显示的操作,会有一些数据要更新
cout<<"绘制"<<endl;
cout<<this<<endl;
}
};
void main()
{
Dialog* _pDlg = new Dialog();//这个永远不会被释放
pDlg->print();
_pDlg = new Dialog();
_pDlg->print();//因为是新的实例,会导致又绘制一个对话框
if(_pDlg)
{
delete _pDlg;
pDlg =NULL;
}
}
这只是个简单的测试小例子,当然一个完整的游戏代码肯定还有很多的地方(某个类,函数)要用到这个对象,我们的目的是整个程序运行时,这个对象至始至终只有一个实例,我们只需要在不同时候的显示前做不同的初始化,当不需要时就把他释放掉
如下的代码:
class Dialog
{
Dialog()//如果使用了new 在编译时就报错
{
}
Dialog(Dialog&)
{
}
public:
void print()
{
//显示的操作,会有一些数据要更新
cout<<"绘制"<<endl;
cout<<this<<endl;
}
static Dialog* getInstance()
{
static Dialog* ins =NULL;
if(!ins)
{
ins= new Dialog();
}
return ins;
}
};
void main()
{
Dialog* _pDlg = Dialog::getInstance();
pDlg->print();
//_pDlg = new Dialog();
_pDlg = Dialog::getInstance();
_pDlg->print();//因为是新的实例,会导致又绘制一个对话框
if(_pDlg)
{
delete _pDlg;
pDlg =NULL;
}
}
似乎一个游戏中要使用单例模式的类还远远的不止这一个啊,如果每个类都打上这些代码,
天啊,“咱要累死了”万一那个不太一样……我们还使用面向对象干什么??干脆还是用回C把,反正效果都是一样的!
当然了,c++之所以一直是个常青树,在设计实现时,早就被想到了(肯能那是不是为单例模式把),这就是模版和友元了,我们就直接使用模版类编写这个单例模式!
代码:
#define NULL 0
template<class INS>
class Singleton
{
public:
//第一种方法
static INS* getInstace()
{
static INS * pIns =NULL;
if(!pIns)
{
pIns = new INS();
}
return pIns;
}
//第二种方法
static INS* getInstace2()
{
static INS Ins;
return &Ins;
}
};
在刚才那失败的代码做点小改动:
class Dialog
{
Dialog()//如果使用了new 在编译时就报错
{
}
Dialog(Dialog&)
{
}
friend Singleton<Dialog>;
public:
void print()
{
//显示的操作,会有一些数据要更新
cout<<"绘制"<<endl;
cout<<this<<endl;
}
};
刚才说了,还有很多的功能需要单例的,我们在仿造一个Dialog的样子写一个类
class Player
{
Player()
{
}
Player(Player&)
{
}
friend Singleton<Player>;
public:
void print()
{
//显示的操作,会有一些数据要更新
cout<<"绘制"<<endl;
cout<<this<<endl;
}
};
void main()
{
Player* player = Singleton<Player>::getInstance();
Dialog* dlg= Singleton<Dialog>::getInstance();
//只是<>中的类型不一样。
delete player ;
delete dlg;
}
注:这只是我自己的一种写法,当然还有很多比这个优秀的高效的写法
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- SRM 576 D2 L2:ArcadeManao,DFS,善于根据实际问题使用最简便的方法
- HDU Error Correction
- 多数开发者误用或者忽略的7种JS的基本方法
- 绘制圆
- ArcGIS 二次开发牛人技术博客
- 单例模式
- hdu 1016
- PMP项目管理知识体系——第十三章 项目干系人管理
- C++Primer读书笔记之左值和右值
- HDU1216--Assistance Required HDU(92)
- NEFU 84 五指山(扩展欧几里得)
- Android_自定义控件之设置文本的大小
- Python读取数据文件转存成矩阵形式
- hdu-4614Vases and Flowers 线段树区间赋值