2011年5月31日星期二

  关于动态单例设计模式

文章:http://www.lilu.name/Html/diannaojishu/2010-09/003468.html中介绍了三种单例设计模式:动态、静态和可配置。然而这三种模式有一个共同的特点就是都使用了常驻内存的静态变量:静态成员变量或静态局部变量。当单例占用了大量内存且不经常使用时,以上三种模式都不适用;反之,如果单例占用内存较小或经常使用,则可以采用上述模式。针对第一种情况,本文给出了如下动态单例设计模式。

基本思路:使用引用计数(参考c++沉思录中的句柄类)+save/load/clear实现。

适用情况:单例占用了大量内存且不经常使用时

优 点:1、单例特性;2、代理内存管理,用户无需考虑内存管理问题;

缺 点:1、需要额外空间用于保存引用计数;2、需要外存保存单例对象,因此需要占用一部分外存空间。

具体实现:

template<class Type>

class SingletonDynamic;

class Test

{

template<class Type>

friend class SingletonDynamic;

public:

//类的公共接口

void output(void)

{

printf("Test:%d\n",use);

}

void clear(void)

{

//清除test外存

}

//..........

private:

static Test* instance(void)

{

if(0==_instance)

{

_instance= new Test;

_instance->load();

}

use++;

return _instance;

}

void save(void)

{

printf("保存test\n");

}

void load(void)

{

printf("装载test\n");

}

Test(void){use=0;printf("构造Test\n");}

~Test(void){printf("析构Test\n");}

private:

static int use;

static Test* _instance;

};

int Test::use=0;

Test* Test::_instance=0;

template<class Type>

class SingletonDynamic

{

public:

SingletonDynamic(void)

{

iptr=Type::instance();

}

SingletonDynamic(const SingletonDynamic& aSingletonDynamic)

:iptr(aSingletonDynamic.iptr)

{

Test::use++;

}

~SingletonDynamic(void)

{

if(--Test::use==0)

{

iptr->save();

delete iptr;

Test::_instance=0;

}

}

SingletonDynamic& operator=(const SingletonDynamic& aSingletonDynamic)

{

//有意留空

}

public:

Type* operator->(void) const {return iptr;}

Type& operator*(void) const {return *iptr;}

private:

Type* iptr;

};

void f1(SingletonDynamic<Test> a)

{

a->output();

SingletonDynamic<Test> b=a;

b->output();

}

void f2(void)

{

SingletonDynamic<Test> a,b,c;

a->output();

b->output();

c->output();

f1(a);

}

int _tmain(int argc, _TCHAR* argv[])

{

f2();

char ch;

scanf("%c",&ch);

SingletonDynamic<Test> a;

a->clear();

return 0;

}

没有评论:

发表评论