我可以看到两个选择,它们对我来说都是合理的。
如果你只是在考虑可能会有用的事情,那么我会选择YAGNI路线,完全不使用它,直到你真正需要它为止。
如果你非常确定你真的需要它,只是还没有编写足够的其他代码来使用它,那么将其设计到类中是值得的,即使你还没有使用它。
但这并不像一个纯虚函数的好情况。纯虚函数意味着1)包含纯虚函数的类不能直接实例化——它只能用作基类,2)为了能够创建派生类的对象,它们必须提供纯虚函数的实现。
换句话说,纯虚函数几乎表示与你的情况相反。在对象存在之前,必须覆盖纯虚函数。你最多只是构建了一个“钩子”,以便未来特定的扩展更容易实现。
我会重复我的建议:除非你非常确定这将被使用,最好只设计你需要的内容,并在此基础上停止。如果你决定需要(或者真的非常想要)包含它,我建议尽量保持松耦合。显而易见的方法是使用访问者模式。这定义了一个单独的访问者类来处理访问和处理节点。树节点类将包括一个额外的函数(传统上命名为
accept
),它接受一个参数:指向访问者对象的指针(或引用)。访问者类通常是一个抽象基类,具有一个成员函数(传统上命名为
visit
)来对节点进行处理。这通常是一个抽象基类。
然后,当您决定每个节点上真正要执行的处理时,您可以从visitor
派生一个新类,覆盖visit
以执行每个节点的处理。树根本不需要修改。这是一个众所周知的模式(即使在C++程序员中也是如此,他们通常对其他模式不太“友好”),因此假设您使用正常的名称,大多数人都会很快和容易地识别它。代码本身通常也非常简单--accept
通常看起来像这样:
struct tree_node;
class visitor {
virtual void visit(tree_node *node) = 0;
};
struct tree_node {
void accept(visitor *v) { v->visit(this); }
};
接下来,为了添加处理,您可以从访问者类中派生出一个新的类,并重写visit
方法以进行所需的处理。树形结构方面不需要做任何修改。这也有一个好处,就是一个访问者类可以被编写用于访问多种类型的节点(即使这些节点不是通过继承相关联的)。