[总结]C++实现一个限制对象实例个数的类
C++实现一个限制对象实例个数的类
absolute8511 总结于 09-3-2
这个问题有两方面的需求,一个是单例模式,只能创建一个对象,另一种是限制创建的对象个数。这两种情况类似,实现原理也是类似的。
它们的基本原理:1.构造函数私有化;2. 提供自己的静态构造函数
对于单例模式,构造一个static对象,以后返回该对象即可。对于限制对象个数的多例模式,需添加一个静态字段记录创建的对象个数,在私有构造函数中对该字段进行检查,在析构函数递减该字段即可。
实现如下:
1. Counted类是所有需要应用该模式的基类。
template<class BeingCounted> class Counted
{
public:
class TooMany{}; //用于抛出异常的类,也可以在对象过多时返回NULL
//用于客户端获取目前已有的对象个数
static size_t objectCount()
{
return numObjects;
}
protected:
Counted();
Counted(const Counted& rhs);
//析构函数使对象计数减1
~Counted()
{
--numObjects;
}
private:
//记录对象个数
static size_t numObjects;
//允许的最多的对象个数,由派生类自己设定限制个数
static const size_t maxObjects;
void init();
};
template<class BeingCounted> size_t Counted<BeingCounted>::numObjects = 0;
template<class BeingCounted> Counted<BeingCounted>::Counted()
{
init();
}
template<class BeingCounted> Counted<BeingCounted>::Counted(const Counted<BeingCounted>& rhs)
{
init();
}
template<class BeingCounted> void Counted<BeingCounted>::init()
{
if(numObjects>=maxObjects)
throw TooMany();
++numObjects;
}
2. 对于需要单例模式的类可以实现如下,从Counted私有派生:
class Limiter1:private Counted<Limiter1>
{
public:
~Limiter1();
//由于私有继承,隐藏了以下两个东西,为了使客户端可见,使用using将它们加入到公有接口中
using Counted<Limiter1>::objectCount;
using Counted<Limiter1>::TooMany;
static Limiter1& GetLimiter1Inst();
private:
Limiter1();
Limiter1(const Limiter1& rhs);
};
//设定限制个数为1,即单例模式
const size_t Counted<Limiter1>::maxObjects = 1;
//客户端将调用该函数获取对象实例
Limiter1& Limiter1::GetLimiter1Inst()
{
static Limiter1 Inst;
return Inst;
}
Limiter1::Limiter1()
{
printf("Limiter1 created!\n");
}
Limiter1::~Limiter1()
{
printf("Limiter1 destroy!\n");
}
3. 限制一定个数的对象的实现方法:
class Limiter2:private Counted<Limiter2>
{
public:
static Limiter2* makeLimiter2();
~Limiter2();
using Counted<Limiter2>::objectCount;
using Counted<Limiter2>::TooMany;
private:
Limiter2();
Limiter2(const Limiter2& rhs);
};
//限制对象个数为4
const size_t Counted<Limiter2>::maxObjects = 4;
//客户端调用该函数获取对象,由于new会调用基类的构造函数,而基类的构造函数会判断实例个数,因此实现了限制个数的目的
Limiter2* Limiter2::makeLimiter2()
{
return new Limiter2();
}
Limiter2::Limiter2()
{
printf("Limiter2 created!");
}
Limiter2::~Limiter2()
{
printf("Limiter2 destroy!");
}