单例模式

来源:互联网 发布:清华经济管理学院知乎 编辑:程序博客网 时间: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;

}

注:这只是我自己的一种写法,当然还有很多比这个优秀的高效的写法

原创粉丝点击