我正在研究一种用C ++编写的有点复杂的数学代码。我正在使用(模板化)树结构进行自适应函数表示。由于某些数学属性,我最终会遇到需要从一种节点更改为另一种节点的情况。这需要在存储和性能方面以透明的方式进行并且开销最小,因为这些结构用于非常繁重的计算。
详细情况如下:我有一个模板化的抽象基类,它定义了一般的双链节点的一般数学和结构属性。每个节点除了跟踪它的子节点之外,还需要来自它的父节点和顶级Tree类的信息。两个类继承自此类,FunctionNode和GenNode。这些类在存储和功能方面非常不同,并且不应该(至少是公开的)彼此的祖先。因此,我想构建一个这样的树:
T N / \ N N / \ G N / \ G G
其中T是树,N是正常的FunctionNode,G是GenNode。问题是N - G转换:N需要有G型子,G是N型父。由于N和G只是堂兄而不是兄弟,我不能将N *转换为G *。 G足以知道N是一个BaseNode,但是N必须以某种方式以多态方式存储G,以便在遍历树时自动调用正确的虚拟。任何想法如何优雅和有效地解决这个问题将不胜感激! :)当然有人可能会破解这个,但由于这是一个非常基础的代码,我想有一个很好的解决方案。未来很可能会有很多这种代码的推导。
致以最诚挚的问候,
Jonas Juselius
特罗姆瑟大学理论与计算化学中心
答案 0 :(得分:5)
委托时不要使用继承。请查看策略设计模式以获取相关指导。
通过使N(N_g)的子类是一元运算符(其他N是二进制的)并且将工作委托给关联的G对象,可以更好地处理“N-G”转换。那么G子树实际上是一个基于G而不是N的不相交的类族。
T
N
/ \
N N
/ \
N_g N
|
G
/ \
G G
“其中一个问题是我事先不知道下一个N是N还是N_g。”
“预先?”什么之前?如果您正在创建N,然后尝试确定它们是否应该是N_g,那么您已经省略了几件事。
您在此过程中过早地实例化了N.
您忘记编写一个N_g构造函数,该构造函数通过复制N来起作用。
您忘记编写一个{克隆'N来创建N_g的replace_N_with_Ng
方法,然后用N_g替换树中的原始N.
多态性的一点是,你不需要事先知道什么是什么。您应该尽可能长时间地创建N或N_g,并将生成的N(或N的子类)对象绑定到树中。
“此外,有时我需要修剪所有G:s,并产生更多N:s,然后再生成更多的G:s。”
精细。你走在树上,用N个实例替换N_g实例为“prune”。你走过树用N_g替换N个实例来生成一个新的/不同的G子树。
答案 1 :(得分:0)
答案 2 :(得分:0)
您是否使用Boost.Any?
在我看来,这似乎是教科书的例子。
答案 3 :(得分:0)
在考虑了这个问题后,我提出了以下想法:
逻辑上,但不是功能上,GenNode是一种功能节点。如果将FunctionNode拆分为两个类,一个包含公共分母,另一个只具有FunctionNode应具有的附加功能,则FunctionNode可以使用私有继承从该类继承。现在,GenNode可以安全地从FunctionNode继承,所有问题都可以像使用虚拟机一样正常解决。有什么意见吗?