继承、组合和多成员变量的优点/缺点

Advantages/Disadvantages of a Inheritance, composition and multiple member variables

本文关键字:缺点 变量 成员 组合 继承      更新时间:2023-10-16

我正在查看Ogre3D代码和WildMagic代码,我发现两者都处理其核心类的方式略有不同。由于我正在创建自己的核心,我想知道哪种做法更好,并且在资源方面可能更好。

在 WildMagic 中,有一个 Matrix 类继承自 Table 类(非多态(。表类可以有 N 行和 N 列,并获取列和行的 getter 和 setter。然后,Matrix 类具有仅对矩阵有意义的功能,并且它方便地从 Table 继承。在这种情况下,向量也可以从 Table 继承(尽管 WildMagic 不这样做(。WildMagic还有一个Transform对象,用于存储节点的本地和派生转换。因此,一个节点将有两个包含必要转换(包括位置、旋转、缩放(的变换对象。

另一方面,在Ogre3D

中,Matrix类不派生自任何东西,Ogre3D的节点具有存储局部和派生位置的变量:Vector localPos; Vector derPos; Matrix localRot; Matrix derRot; etc.

现在请记住,这些是每帧将使用/更新/修改数千次的核心对象,如果您意识到在拥有依赖于这些核心类的完整游戏时存在性能瓶颈,则很难更改它们。

所以现在的问题是:

  1. 从表类继承的矩阵类与首先执行所有操作的矩阵类是否有相关的成本
  2. 在 Node 类中拥有 3 个转换对象的实例与通过成员变量公开底层数据类型是否有相关的成本(我意识到在这两种情况下,它都是组合,只是在一种情况下,转换wrapper,而在另一种情况下,转换直接公开。我想这个问题可以改写为:Does a wrapper have a cost (considering it is an object that needs to be created and destroyed)?
  3. 假设我正在编写一个应用程序,其中每个计算(甚至是简单的 Vector 加法(都很重要。你会改变你的选择吗?

非常好,复杂的问题,有很多很多答案。 我会尽我所能解决这些问题,但至少在我看来,总体答案将比一个人可能做的事情更多地满足你的需求。

1(继承总是有代价的,尽管它非常微小。 这个问题真的没有一个简单的答案,所以我可能会读到:http://www.hackcraft.net/cpp/templateInheritance/

2(任何必须创建或销毁的东西都有成本。 一般来说,包装东西会让项目上的很多人"更安全",但除此之外,我觉得它没有用或不值得。 就像继承一样,包装东西的成本非常小。

3(如果每个计算都很重要,那么如果您不必包装,请不要包装东西。 至少对于简单的数学课程,只需使用模板即可轻松使用而不是继承。

总体而言,对于矩阵和矢量的基本数据结构,如果程序在PC或控制台上使用任何一种方法,您都不会杀死程序。 缓慢的内存管理器和内存分配将比继承向量和矩阵类更能杀死您的游戏。

如果您不进行虚拟函数调用,那么从纯粹的性能角度来看,这无关紧要。我个人不赞成继承而不是任何其他解决方案。编译器将优化小型包装器对象。但是,我并不鼓励您将OGRE3D视为优秀设计的巅峰之作 - 它们充斥着单例。

对于 (1(,你肯定没有多态性吗? 在继承方面,虚拟函数调用对效率的影响最大。 如果没有虚函数,两者之间几乎没有区别,绝对没有可以概括的区别。 也许在一种情况下,对象在内存中的布局会有所不同,也许你会有不同的大小,在一种情况下浪费更多的缓冲区,诸如此类。

对于 (2(,这一切都归结为代码被优化的可能性。通常,如果相关函数都很容易内联,那么在轻量级包装器案例中不会有很多实际的函数调用。 但同样,内存布局之类的事情可能会产生后果。 抽象地很难预测。

对于(3(,我没有做出选择,所以我不知道你指的是什么:-P