本篇笔记包含 Term 25~29。

Term 25:将 constructor 和 non-member functions 虚化

  1. 事实上构造函数不能是虚函数,但某些情况下,我们可能需要使用虚函数性质的 constructor,这时候,我们可以创建一个虚函数 clone(),在 clone 中调用构造函数。
  2. 类似的,non-member functions 也不能是虚函数,但是我们可以定义一个接口函数,接收基类,再调用类中的虚函数,达成类似的效果。

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

最好的做法是设计一个用来计算对象个数的 Base Class,

template <typename T>
class Counted {
 public:
  class TooManyObjects {};  // 会被抛出的异常
  static int objectCount() { return numObjects; };
 protected
     :  // 构造函数和析构函数定义为 protected,并且 Counted 类应被 private 继承
  Counted();
  // 省略其它构造函数,实现中应调用 init()
  ~Counted() { --numObjects; };
 private:  // numObjects 和 maxObjects 定义为 stactic,实现对象计数
  static int numObjects;
  static const size_t maxObjects;
  void init();
};
template <typename T>
int Counted<T>::numObjects = 0;
template <typename T>
Counted<T>::Counted() {
  init();
}
template <typename T>
void Counted<T>::init() {
  if (numObjects >= maxObjects) throw TooManyObjects();
  ++numObjects;
}

// 私有继承 Counted
class Foo : private Counted<Foo> {
 public:  // 通过 newFoo 间接调用构造函数
  static Foo* newFoo();
  using Counted<Foo>::objectCount;
  ~Foo();
 private:  // 构造函数私有
  Foo(){};
};
template <>
const size_t Counted<Foo>::maxObjects = 10;  // 继承 Counted 时指定 maxObjects
Foo* Foo::newFoo() { return new Foo(); }

Term 27:要求(或禁止)对象产生于 heap 之中

  1. 要求对象产生于 heap 之中:将构造或者析构函数设置为非 public 即可
  2. 判断对象是否在 heap 中:编写一个基类,重载 operator new,调用 new 的时候把指针存入一个 list(数组,vector 之类的也可以),设置一个接口函数,判断当前对象的指针是否在 list 当中。继承这个类的派生类,通过接口可以判断对象是否在 heap 中
  3. 禁止对象产生于 heap 之中:将 operator new/delete 设置为非 public 即可

Term 28:Smart Pointers(智能指针)

智能指针使得一下几件事情更加有控制权:

  1. 构造和析构
  2. 复制和赋值(Copying and Assignment)
  3. 解引(Dereferencing)

Term 29:Reference counting(引用计数)

适合使用引用计数类的场景:

  1. 相对多数的对象共享相对少量的实值
  2. 对象实值的产生或销毁成本很高,或是它们使用许多内存