第五章,技术

26-限制某个class所能产生的对象数量

实现0个对象限制

class Printer { 
public:
...
private:
Printer() {}
};

实现单一对象限制

实现单一对象限制的最有效方法就是将constructor变成private,并提供获取单一对象的接口

class Printer { 
public:
static Printer& getInstance()
{
static Printer instance;
return instance;
}
...
private:
Printer() {}
};

实现对象数量(n>1)限制

可复用的计数器基类模板设计

template <class BeingCounted>
class Counted {
public:
class TooManyObjects {}; // 自定义异常类
static int objectCount() { return numObjects; }

protected:
Counted() { init(); }
Counted(const Counted& rhs) { init(); }//参数rhs,一种惯用简写,right-hand-side (右手边)意为这是一个应该出现在等号右边的变量
~Counted() { --numObjects; }

private:
static int numObjects;
static const int maxObjects; // 最大允许数量,由派生类特化

void init() {
if (numObjects >= maxObjects) throw TooManyObjects();
++numObjects;
}
};

限制10个Printer对象

class Printer : private Counted<Printer> { //private继承,继承的成员都为private; 继承了Counted基类后,构造时会先调用基类Counted构造,其中调用init函数从而实现对象个数限制
public:
static Printer* makePrinter() { return new Printer(); }
using Counted<Printer>::objectCount; //将基类的 objectCount "提升"为 public(using这种写法,单独公开private锁住的成员objectCount)
using Counted<Printer>::TooManyObjects;
private:
Printer() {}
};

//类模板的静态成员定义必须使用显式特化语法 template<> (MSVC上可能可以直接省略template<>,但是属于非标准行为,不可移植)
template<> const int Counted<Printer>::maxObjects = 10;//一旦实例化10个以上Printer对象,就会抛出异常
template<> int Counted<Printer>::numObjects = 0;