今天看到搜索2叉树一章, 后面还有红黑树等等, 于是想, 所有树的遍历方式都雷同, 干脆写一个叫做BinaryTree的抽象类, 并实现基本的二叉树行为, 比如遍历等。 针对Tree写traverse, insert, delete等虚函数, 然后其他树派生,可以替换不同的Tree来实现。 想到就做, 写到traverse的实现, 应该是这样子的:
template<class Ty>
class BinaryTree
{
public:
template<Function f>
virtual void traverse(Function f);
}
首先, traverse需要接受一个函数对象来进行traverse, 其次traverse应该是一个虚函数, 由派生类来实现。 可惜的是: 这两个冬冬是矛盾的, template类不能是虚的。
然后开始冥思苦想, 应该怎么办, 想了一通以后, 突然惊醒。 幸好用泛化实现, 发现了在这个问题上,好像走进了一个面向对象编程的误区。 BinaryTree应该是多态的么? 应该有一个抽象基类么? 不应该! BinaryTree作为一个抽象概念, 实际上只有在教学上有意义, 在实际运用中, 最原始的BinaryTree实际上根本没有任何用处, 真正使用的都是具体实现的各种具体类, 比如红黑树, 二叉搜索树, 平衡树, B树等等。 这些数据结构本身也都属于基本的数据结构, 而且除了在形态上都可以归结为树以外,使用时差别是相当大的, 在应用领域中, 是要根据实际情况来选用不同的数据结构,一旦选定, 就很少变动了, 对性能要求很高, 也不应该有虚函数这种浪费性能的东西。 而且他们之间的类似程度可能也就和vector与list之间一样, 都是一种容器, 除了结构相似, 意义完全不同。所以根本不需要所谓的抽象基类。是应该单独实现的, 最多只要满足stl容器的约束条件就是了。