相关疑难解决方法(0)

使用断言或例外通过合同设计?

通过合同编程时,函数或方法首先检查其前提是否已满足,然后才开始履行其职责,对吗?两个最重要的方式做这些检查是通过assertexception.

  1. 断言仅在调试模式下失败.确保(单元)测试所有单独的合同前提条件以确定它们是否确实失败是至关重要的.
  2. 在调试和释放模式下异常失败.这样做的好处是,测试的调试行为与发布行为相同,但它会导致运行时性能下降.

你觉得哪一个更好?

请参阅此处的相关问题

assert design-by-contract exception

121
推荐指数
5
解决办法
2万
查看次数

在C++中使用assert()是不好的做法?

我倾向于在我的C++代码中添加许多断言,以便在不影响发布版本性能的情况下简化调试.现在,assert是一个纯C宏设计,没有考虑到C++机制.

另一方面std::logic_error,C++定义了在程序逻辑中存在错误(因此名称)的情况下抛出的内容.抛出一个实例可能只是一个完美的,更多的C++替代品assert.

问题是,assert并且abort两者都立即终止程序而不调用析构函数,因此跳过清理,而手动抛出异常会增加不必要的运行时成本.解决这个问题的一种方法是创建一个自己的断言宏SAFE_ASSERT,它就像C对应物一样工作,但在失败时抛出异常.

我可以想到关于这个问题的三种看法:

  • 坚持C的主张.由于程序立即终止,因此更改是否正确展开并不重要.此外,#define在C++中使用s同样糟糕.
  • 抛出异常并在main()中捕获它.允许代码在程序的任何状态下跳过析构函数都是不好的做法,必须不惜一切代价避免,并且调用terminate()也是如此.如果抛出异常,则必须捕获它们.
  • 抛出异常并让它终止程序. 终止程序的例外是可以的,并且由于NDEBUG这种情况在发布版本中永远不会发生.捕获是不必要的,并公开内部代码的实现细节main().

这个问题有明确的答案吗?有专业的参考吗?

编辑:跳过析构函数当然没有未定义的行为.

c++ assert coding-style

83
推荐指数
5
解决办法
3万
查看次数

C++错误代码vs ASSERTS vs Exceptions选择选择:(

代码有问题

我已经听到(和反刍)围栏两侧的C++异常口头禅.它已经有一段时间了,我只想再次集中自己,这个讨论特定于我链接的代码(或容器等低级类),以及它的依赖关系.我曾经是一个使用C程序员的防御和错误代码,但这是一个令人厌倦的实践,我现在编程的更高层次的抽象.

所以我重写一个容器类(和它的依赖项)更灵活,读取更好(迭代器没有atm).正如您所看到的,我将返回枚举的error_codes,我知道我将在调用站点测试它们.容器用于AST的运行时构建,初始化和只读.它们的例外是防止容器被天真地使用(将来可能由我自己使用).

我在这堂课的所有地方都有例外,他们让我觉得很脏.我很感激他们的用例.如果我有选择,我可能会完全关闭它们(Boost使用了很多例外,我正在建立Boost,是的,我知道他们可以被禁用,但是在罗马时......).我可以选择用error_codes替换它们但是嘿,我不会测试它们,那么重点是什么?

我应该用ASSERTS替换它们吗?[1] [2] [3]这个膨胀的人是什么?每个函数调用点都能获得额外的机器吗?或者只有那些有捕获条款的人?既然我不会抓住这些例外,我不应该成为这种膨胀的受害者吗?ASSERTS不会进入发布版本,在基本原始类(即容器)的上下文中,这甚至不重要吗?我的意思是逻辑错误进入最终构建的可能性有多高?

既然我们想回答有针对性的问题,那么这就是我的:你会做什么,为什么?:d

不相关的链接:错误代码并让他们在异常中备份.

编辑2在这种特殊情况下选择在ASSERT和异常之间,我认为异常是最有意义的,正如我上面提到的,容器只在初始化后被读取,并且大多数异常在初始化期间被触发.

c++ exception assertions

6
推荐指数
1
解决办法
2773
查看次数