2012-12-07 30 views
2

我正在写一个程序,我创建了一个std :: POD结构的向量。该结构的一个成员是唯一标识符。应该在这种情况下运营商==或!=投掷?

为了能够使用std :: binary_search,我必须为结构实现运算符<。遵循指南here,我正在为==,!=,<,>,> =和< =写入整套重载。

这提出了一个问题,我不知道如何处理。该矢量将按照我分配每个结构的唯一ID进行排序。如果两个结构具有相同的标识符,则它们是相同的。但是,如果两个结构体在其他成员中具有相同的标识符但数据不同,那么情况就会出现。

这不应该发生。让比较运算符检查剩余的字段,然后抛出异常(如果它们不同但ID相同)是否合适?什么样的例外将是最合适的?

+2

我认为一个'std :: set'与基于id的比较更适合这个任务。 – chris

+3

如果你希望这个条件在运行时是可以恢复的,那么'throw'就是合适的。如果不是,'assert'可能是更好的选择。 – phonetagger

+0

@chris我去了std :: vector,因为我需要内存连续。我不知道该集(或任何其他有序容器)提供了这种保证。 – Kian

回答

7

这仅仅是对SCombinator's answer.

,你说的其实是一个扩大“这应该不会发生。”意味着你想使用一个断言,而不是一个例外(或两者的组合)。一个例外会隐藏错误 - 好吧,不会隐藏,但你可以抓住它并继续。它更适合于你没有真正计划的特殊情况 - 例如,你试图打开一个不存在的文件。这不是逻辑的一部分,该文件不存在,它是你的小弟不小心删除了你的文件,或者是一种认为它是病毒的激进反病毒,或者其他 - 这只是一种特殊情况。

如果具有相同ID但不同的成员是不应该发生的事情,那基本上就是断言。这是逻辑的一部分 - 如果你愿意的话,这是要求的一部分。抛出一个异常只是指出了这一点,但并没有真正的方法可以从中恢复。当你意识到错误的时候,已经晚了2点。你有两个具有相同ID的对象,但不同,你不知道哪一个是正确的,你不知道为什么不正确的对象存在,等等。你可能甚至不想从中恢复。应用程序已经处于错误状态 - 两个相互矛盾的对象已经存在。你的应用程序处于不可恢复状态 - 如果你继续这样做,你可能会得到错误的结果或更糟的结果。

如果它不是一个关键的断言,你也可以随后抛出异常,并提供一个干净的方式来关闭应用程序,但这只是一种美化。

一般来说,我遵循一个简单的规则 - 如果是在特殊情况下可能发生的事情,我会使用例外。如果它永远不会发生,如果它确实存在,意味着代码中的逻辑严重错误,我使用断言(也可能是强制崩溃)。

+0

谢谢。然而,只是为了澄清一点,如果ID是相同的,并且成员不同,则不会发生错误。 – Kian

+0

@Kian啊,好的。现在好多了? (虽然没有改变推理):) –

+0

是的,谢谢你的解释。它确实使它更清楚何时使用它们。 – Kian

2

如果这样的事情是一个逻辑错误,你应该使用一个assert

+0

断言在这里使用是正确的,但是你可能想要扩展为什么,以及为什么它比这种情况下的例外更好。 –

0

你可以使用一个map这是一个二叉搜索树实现,虽然你会复制一个id。再次,你甚至不需要将id存储在结构中,因为它们应该是唯一的。

// Example POD struct. 
struct MyStruct 
{ 
    int id; // Redundant. 
    char a;  
} 

std::map<int, MyStruct> myMap; 
MyStruct m; m.id = 1; 
myMap[m.id] = m; 
// Or simply.. 
myMap[1] = m; 
2

好了,你要问自己几个问题:

1)这是可能发生的测试(如信号的错误),但在正常执行过程中不会发生?如果答案是肯定的,请使用assert

2)这是否会在正常运行时发生,如果是这样,程序是否可以恢复并继续执行?如果答案是肯定的,那就抛出一个错误,抓住并处理它。

3)这是否会在正常运行时发生并且是不可恢复的?如果是,请拨打abort或类似的东西(exit, terminate)或抛出一个你不打算处理的异常。

+0

如果只有1)那么简单。如何判断是否只在测试期间发生了某些错误,但从未在正常执行期间发生错误 –

+0

或者希望最好,或者完全停止使用assert,我想。 (我的意思是使用完整的测试而不是断言。) 它并不总是很简单。但有时可能。 –

1

创建数据时应该拒绝不良数据。比较运营商不去清除错误;那么应该在之前完成该程序执行任何严重的数据操作。所以这个问题的答案是否定的,operator==operator!=不应该对不良数据抛出异常;他们应该假设传递给他们的数据是有效的。