我是一些家谱软件(用C++和Qt编写)的开发人员。直到我的一位客户给我邮寄了一份错误报告,我才发现问题。问题是,客户有两个孩子和自己的女儿,因此,由于错误,他无法使用我的软件。
这些错误是我对正在处理的族图的各种断言和不变量的结果(例如,在走完一个循环后,程序声明X不能既是Y的父亲又是Y的祖父)。
如何在不删除所有数据断言的情况下解决这些错误?
我是一些家谱软件(用C++和Qt编写)的开发人员。直到我的一位客户给我邮寄了一份错误报告,我才发现问题。问题是,客户有两个孩子和自己的女儿,因此,由于错误,他无法使用我的软件。
这些错误是我对正在处理的族图的各种断言和不变量的结果(例如,在走完一个循环后,程序声明X不能既是Y的父亲又是Y的祖父)。
如何在不删除所有数据断言的情况下解决这些错误?
当前回答
撇开潜在的法律影响不谈,你显然需要将家谱上的“节点”视为前任,而不是假设节点可以是唯一的人。
让树节点包含一个人以及继任者,然后可以在树的更深处创建另一个节点,该节点包含同一个人和不同的继任者。
其他回答
最重要的是避免产生问题,所以我认为你应该使用直接关系来避免循环。
正如@markmywords所说,#包括“fritzl.h”。
最后,我不得不说重新检查您的数据结构。也许那边出了问题(也许双向链接列表解决了您的问题)。
看来你(和/或你的公司)对家谱应该是什么有着根本的误解。
让我澄清一下,我也在一家公司工作,该公司的产品组合中有一个家谱(作为其产品之一),我们一直在解决类似的问题。
在我们的案例中,我假设你的案例也是如此,问题来自于GEDCOM格式,它对家庭应该是什么非常有见解。然而,这种格式包含了一些关于家庭树真实外观的严重误解。
GEDCOM有很多问题,例如同性关系不相容、乱伦等。现实生活中发生的事情比你想象的要多(尤其是当追溯到1700-1800年时)。
我们已经将我们的家谱模型化为现实世界中发生的事情:事件(例如,出生、婚礼、订婚、结婚、死亡、收养等)。我们没有对这些事情施加任何限制,但逻辑上不可能的事情除外(例如,一个人不能成为自己的父母,关系需要两个人,等等)
缺乏验证为我们提供了一个更“真实”、更简单、更灵活的解决方案。
对于这个具体的案例,我建议删除这些断言,因为它们并不普遍适用。
为了显示问题(可能会出现),我建议根据需要多次绘制同一节点,通过选择其中一个副本点亮所有副本来暗示重复。
一些答案显示了保持断言/不变量的方法,但这似乎是滥用断言/不变量。断言是为了确保应该是真的东西是真的,不变量是为了确保不应该改变的东西不会改变。
你在这里断言的是乱伦关系是不存在的。显然它们确实存在,因此您的断言是无效的。您可以解决这个断言,但真正的错误在于断言本身。应删除断言。
你应该关注真正为你的软件创造价值的东西。为一个消费者提供服务所花费的时间是否值得许可证的价格?可能不会。
我建议您向这位客户道歉,告诉他他的情况超出了您的软件范围,并向他退款。
这就是为什么像“Go”这样的语言没有断言的原因之一。它们被用来处理那些你可能没有想到的案例,所有这些都太频繁了。你只应该断言不可能,而不仅仅是不可能。做后者会给断言带来坏名声。每次你输入assert(,走开十分钟,认真思考一下。
在你特别令人不安的案例中,在罕见但可能的情况下,这样的断言是假的,这是可以想象的,也是令人震惊的。因此,在你的应用程序中处理它,如果只是说“这个软件不是为处理你所呈现的场景而设计的”。
断言你的曾、曾、曾祖父是你的父亲是不可能的,这是合理的做法。
如果我是为一家被雇佣来测试你的软件的测试公司工作的话,我当然会提出这种情况。为什么?每一个年轻而聪明的“用户”都会做同样的事情,并对由此产生的“错误报告”津津乐道。