14.6.1 通过指针保存多态类型
因为一个派生类指针同时也是一个基类指针,所以这个问题的标准解决方案[Meye1996, Dewh2003, Sutt2000]是将指向实例的指针保存在数组(或者std::vector)中并处理之。这种做法完全预防了该问题,并且在许多情况下的确是首选解决方案。
然而,这仅仅覆盖了那些你希望通过(虚)函数来操纵类型的情况。由于通常我们需要为C-API结构提供简单的外覆类(参见3.2节和4.4节),所以这个途径并不总是合适的。而且有时候我们还会需要从"非虚函数表多态(non-vtable-polymorphic)"的类型进行继承(尽管这种情况非常罕见。参见第21章)。
最后一个缺点是它对操纵代码的算法强加了"因对每个元素进行额外的间接调用而带来的"开销,同时还有为"分配并实例化数组及其各个指针元素"而调用的代码的开销,这两项开销是相互独立的,如程序清单14.5所示:
程序清单14.5
- void process_array(Base *ab[], size_t cb)
- {
- for(Base **end = ab + cb; ab != end; ++ab)
- {
- print_Base(**ab); // 处理每一个元素。可能需要先测试一下*ab是否为null
- }
- }
-
- int main()
- {
- Derived ad[10];
- Base *apb[dimensionof(ad)];
- for(int i = 0; i < dimensionof(ad); ++i)
- {
- apb[i] = &ad[i];
- }
- process_array(apb, 10); // 没问题,但是这么做值得吗?
- . . .
-
由于我们正试图探索所有可能的选择,所以接下来我们继续考察一些替代方案。