编程交流与学习--More Effective C++的学习-Item M26:限制某个类所能产生的对象数量

以下为摘要(本章后面不知所云):

阻止建立某个类的对象,最容易的方法就是把该类的构造函数声明在类的private域。

    class Printer {

public:

  static Printer& thePrinter();

  ...

private:

  Printer();

  Printer(const Printer& rhs);

  ...

};

Printer& Printer::thePrinter()

{

  static Printer p;

  return p;

}

    用户使用printer时有些繁琐:

Printer::thePrinter().reset();

Printer::thePrinter().submitJob(buffer);

    另一种方法是把thePrinter移出全局域,放入namespace(命名空间)(参见Effective C++条款28)。命名空间是C++一个较新的特性。任何能在全局域声明东西也能在命名空间里声明。包括类、结构、函数、变量、对象、typedef等等。把它们放入命名空间并不影响它们的行为特性,不过能够防止在不同命名空间里的实体发生命名冲突。把Printer类和thePrinter函数放入一个命名空间,我们就不用担心别人也会使用PrinterthePrinter名字;命名空间能够防止命名冲突。

    thePrinter的实现上有两个微妙的不引人注目的地方,值得我们看一看。第一,唯一的Pritner对象是位于函数里的静态成员而不是在类中的静态成员,这样做是非常重要的。在类中的静态对象实际上总是被构造(和释放),即使不使用该对象。与此相反,只有第一次执行函数时,才会建立函数中的静态对象,所以如果没有调用函数,就不会建立对象。(不过你得为此付出代价,每次调用函数时都得检查是否需要建立对象。)建立C++一个理论支柱是你不需为你不用的东西而付出,在函数里,把类似于Printer这样的对象定义为静态成员就是坚持这样的理论。你应该尽可能坚持这种理论。

    与一个函数的静态成员相比,把Printer声明为类中的静态成员还有一个缺点,它的初始化时间不确定。我们能够准确地知道函数的静态成员什么时候被初始化:“在第一次执行定义静态成员的函数时”。而没有定义一个类的静态成员被初始化的时间。C++为一个translation unit(也就是生成一个object文件的源代码的集合)内的静态成员的初始化顺序提供某种保证,但是对于在不同translation unit中的静态成员的初始化顺序则没有这种保证(参见Effective C++条款47)。在实际使用中,这会给我们带来许多麻烦。当函数的静态成员能够满足我们的需要时,我们就能避免这些麻烦。在这里的例子里,既然它能够满足需要,我们为什么不用它呢?

    第二个细微之处是内联与函数内静态对象的关系。 “带有内部链接的函数可能在程序内被复制(也就是说程序的目标(object)代码可能包含一个以上的内部链接函数的代码),这种复制也包括函数内的静态对象。”所以不要建立包含局部静态数据的非成员函数。

   也许你认为只需简单地计算对象的数目,一旦需要太多的对象,就抛出异常,这样做也许会更好。此法的核心思想就是使用numObjects跟踪Pritner对象存在的数量。当构造类时,它的值就增加,释放类时,它的值就减少。如果试图构造过多的Printer对象,就会抛出一个TooManyObjects类型的异常.这种限制建立对象数目的方法有两个较吸引人的优点。一个是它是直观的,每个人都能理解它的用途。另一个是很容易推广它的用途,可以允许建立对象最多的数量不是一,而是其它大于一的数字。

l         建立对象的环境

l         允许对象来去自由

l         一个具有对象计数功能的基类

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值