本篇笔记包含 Term 25~29。
Term 25:将 constructor 和 non-member functions 虚化
- 事实上构造函数不能是虚函数,但某些情况下,我们可能需要使用虚函数性质的 constructor,这时候,我们可以创建一个虚函数
clone()
,在clone
中调用构造函数。 - 类似的,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 之中
- 要求对象产生于 heap 之中:将构造或者析构函数设置为非 public 即可
- 判断对象是否在 heap 中:编写一个基类,重载
operator new
,调用 new 的时候把指针存入一个 list(数组,vector 之类的也可以),设置一个接口函数,判断当前对象的指针是否在 list 当中。继承这个类的派生类,通过接口可以判断对象是否在 heap 中 - 禁止对象产生于 heap 之中:将
operator new/delete
设置为非 public 即可
Term 28:Smart Pointers(智能指针)
智能指针使得一下几件事情更加有控制权:
- 构造和析构
- 复制和赋值(Copying and Assignment)
- 解引(Dereferencing)
Term 29:Reference counting(引用计数)
适合使用引用计数类的场景:
- 相对多数的对象共享相对少量的实值
- 对象实值的产生或销毁成本很高,或是它们使用许多内存