gpt4 book ai didi

c++ - 如果您使用多个 is-a 继承,您是否不想使用相互基类的虚拟继承?

转载 作者:IT老高 更新时间:2023-10-28 21:37:04 34 4
gpt4 key购买 nike

如果你有通过公共(public)继承实现的 is-a 继承关系,并且有一个菱形继承,你会得到类似的东西:

  • 一个流类
  • 从流派生的输入流和输出流类
  • 派生自两者的输入/输出流类

在这种情况下,正如在标准库 (?) 中使用的那样,在 iostream 既 is-a istream 和 is-ostream 的范围内,istream is-a 流和 ostream is-a 流,而且它们是 相同的 流,流中的任何函数,适用于 iostream,都应该处理相同的底层结构。

在C++中,为了共享istream和ostream中stream的拷贝,必须虚拟继承。

但是,如果您愿意,您可以虚拟继承,并且每次引用基类的成员时,指定两个拷贝中的哪一个(一个在 istream 中或一个在 ostream 中)想要(通过强制转换或使用 scope::blah)。

我的问题是,[编辑:是否有任何其他情况]除了“这不是真正的 is-a 关系,当它在概念上无效时,我顽皮地使用公共(public)继承作为语法便利”或“我永远不需要从最派生的类中多态地引用基类,因此非常小的开销是不值得的”,有任何理由非虚拟继承并拥有两个基类拷贝在概念上是有效的类,每个姐妹中间类一个?

最佳答案

我们来看一个简单的例子。

   B           B1   B2
| \ /
D D

在左边,我们发现了一个派生自单个低音的类。在 OO 设计中,具有尊重 Liskov Substitution Principal 的 is-a 关系显然是合理的。

在右边,两个 B1B2D 的独立基, 和 D可以使用 B1* 进行多态访问或 B2* (或引用)。希望我们可以接受这也是一种有效的 OO 设计(尽管 Sun 认为它对 Java 程序员来说压力太大了;-P)。然后考虑从 B1 中排除一些基本功能。和 B2并使其可重用:假设它们都在任意数字列表上进行操作,它们可以合理地直接授予/public访问:

   Container<int>   Container<int>
\ /
B1 B2
\ /
D

如果这还没有点击,也许:

   Container<int>   Container<int>
\ /
Ages Heights
\ /
Population

按理说Ages是一个 Container<int> ,尽管它可能会添加一些方便的功能,例如 average , min , max , num_teenagers . Heights 相同,可能具有不同的便利功能。显然是 Population可以合理地替换为 AgesHeights集合(例如 size_t num_adults(Ages&); if (num_adults(my_population)) ... )。

这里的重点是,每个支持容器并不意味着与进一步派生的类(如 Population)具有 1:1 的关系。 ;相反,它的意思是与其直接派生的类完全是 1:1

同样,使用组合还是继承是接口(interface)设计决定,但以这种方式公开公开容器不一定无效。 (如果担心维护 Population 不变量,例如 Ages::empty() == Heights::empty(),可以将 Container<int> 的数据变异函数设为 protectedconst 成员函数为 public。)

如您所见,PopulationContainer<int> 没有明确的 is-a 关系并且代码可能需要明确的消歧。那是合适的。当然,Population 也是可能的,也是合理的。源自 Container<int>如果它存储了一些其他数字集,但这将独立于间接继承的容器。

My question is, other than "This isn't really an is-a relationship, I used naughtily used public inheritance as a syntactic convenience when it wasn't conceptually valid"

我认为上述的 is-a 关系或概念有效性没有任何问题,如果你这样做,请解释......

"I never need to refer polymorphically to the base class from the most-derived class so the incredibly small overhead isn't worth it"

我认为很明显我只是在基于自然对象关系进行数据建模,而不是一些可疑的优化。从基础中分解出来的支持容器类是实际使用的,并且必须在每个基础中独立。

关于c++ - 如果您使用多个 is-a 继承,您是否不想使用相互基类的虚拟继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5388667/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com