C++ 项目设计 - 私有继承和"is a"关系

c++ Project Design - private inheritance and "is a" relationship

本文关键字:is 关系 继承 项目 C++      更新时间:2023-10-16

我想通过私有继承来扩展一个类。

基类为:Graph<T>

派生结果为:Tree<T>

我们知道树是一个特定的图,所以我想扩展我的图类,而不让用户使用图类的 PUBLIC 方法。

制作:

template <typename T> class Tree : public Graph<T>{
    .
    .
    .
}

有效,但我不想使用 Graph 类方法更改我的树状态。用户必须使用树类特定的方法。我想我应该使用私人继承来得到我想要的东西。

问题是我不能失去"是"的关系,因为树实际上是一个图。

什么是好的设计,才能使事情变得好和语义有序?

谢谢

好吧,你不能同时拥有它。 is-a 关系完全意味着用户可以在指针(或引用)上使用任何Graph定义的非虚拟、未重写的函数来Tree并实现预期结果。

如果不能允许用户调用这些函数,则意味着is-a关系根据定义是不合适的,您应该选择私有继承。

私有继承不是一个好主意 - 有关更多详细信息,请参阅这篇文章。

但是,我认为您以错误的方式处理问题。如果树是图形,那么可能想要对图形执行的任何操作都是有效的。应该允许客户这样做。操作应以有意义的方式构建。如果您发现某些操作没有,那么这可能不是继承的正确使用。

请记住,在图论/组合数学中,树是图,但在计算机科学中,这种关系是脆弱的。树和图形表示为数据结构的方式完全不同,这使得代码共享变得麻烦。

面向对象并不总是很好用。树是一种特殊类型的图形。但是在特殊性方面,它比一般图形更受限制和更简单,并且支持更少的操作。因此,您可以编写一个允许任意数量的节点和任何拓扑的图库,然后在树层中限制拓扑。或者你可以说树根本不继承图。或者你可以说有一个抽象的"图库",然后可以用树、一般图、有向无环图、平衡树等来实例化。

我建议最后一个是你想要的。因此,编写一个至少一个虚拟成员函数设置为 null 的abstract_graph基类。

然后你可以私下继承。这取决于树客户端是否关心树是图。然而,私人继承并不常见。