![]() |
1
3
你可以用助推器。异常库来帮助定义异常层次结构。 刺激。异常库支持:
该框架的局限性将为您提供合理定义的设计参数。 |
![]() |
2
2
一般来说,异常类应该是简单的、自给自足的结构,并且从不分配内存(比如
|
![]() |
3
2
在考虑允许代码处理异常之前,异常的首要任务是能够准确地向用户和/或开发人员报告出了什么问题。一个异常类不能报告OOM,但只是在不提供任何关于程序崩溃原因的线索的情况下崩溃了程序,这是不值得的。OOM现在变得非常普遍,32位虚拟内存已经耗尽。 向异常类中添加大量帮助器方法的问题在于,它会迫使您进入一个不一定想要或需要的类层次结构。现在需要从std::exception派生,这样就可以用std::bad_alloc做一些事情。当您使用一个库时,如果它包含的异常类不是从std::exception派生的,那么您就会遇到麻烦。 |
![]() |
4
2
看看std异常,它们都在内部使用std::string。
我通常从运行时错误(或其他标准异常之一)派生出我的异常。 |
![]() |
5
2
所以,当你的应用程序致命失败时,你不希望它完全终止吗?让析构函数运行,刷新文件缓冲区或日志,甚至可能向用户显示一条错误消息(或者更好,显示一个错误报告屏幕)?
为什么这是一个公平的权衡?为什么这是一种权衡 全部的 ? 权衡意味着你要 一些 对单一责任原则做出让步,但据我所知,你不会这么做。你只是简单地说“我的例外应该做一切”。这几乎不是一种权衡。 和SRP一样,答案应该是显而易见的:让exception类做所有事情,你会得到什么?为什么记录器不能是一个单独的类?为什么必须由异常执行?它不应该由异常处理吗 处理者 ? 您可能还希望进行本地化,并提供不同语言的语法错误消息。所以,在构造异常类时,应该走出去读取外部资源文件,寻找正确的本地化字符串?这当然意味着另一个潜在的错误源(如果找不到字符串),会增加异常的复杂性,并要求异常知道其他不相关的信息(用户使用的语言和语言环境设置)。格式化的错误消息可能取决于它的显示方式。也许在记录、显示在消息框中或打印到标准输出时,它的格式应该不同。exception类要处理的更多问题。更多可能出错的事情,更多可能出错的代码。 你的异常尝试的越多,出错的事情就越多。如果它试图登录,那么如果磁盘空间不足会发生什么?也许你也会假设无限的磁盘空间,只是忽略了如果发生这种情况,你会扔掉所有的错误信息? 如果您没有日志文件的写入权限怎么办? 根据经验,我不得不说,没有什么事情比这更烦人了 由于发生错误,无法获取有关刚刚发生的错误的任何信息 .如果您的错误处理无法处理发生的错误,那就不是真正的错误处理。如果异常类无法在不引发更多异常的情况下处理创建和抛出的异常, 重点是什么 ? 通常,使用SRP的原因是,向类添加的复杂性越高,就越难确保正确性,也就越难实现 懂 密码。这仍然适用于异常类,但您还需要考虑第二个问题:添加到异常类的复杂性越高,发生错误的机会就越多。一般来说,你不希望出现错误 在抛出异常时 。毕竟,您已经在处理另一个错误。
但是,“异常类不应包含
表示他不介意应用程序终止的人说,如果出现错误,他不会向用户提供反馈 是的,您的异常应该包含生成友好、可读的错误消息所需的所有数据。在解析器的情况下,我想说的是:
根据这些信息,你可以 在处理错误时 为用户生成友好、健壮的错误消息。如果你愿意,你甚至可以将其本地化。你可以把它本地化 当你处理异常时 . 通常,异常类供程序员使用。它们不应包含或构建针对 使用者 。正确创建可能很复杂,在处理错误时应该这样做。 |
![]() |
6
1
C++标准要求异常没有抛出拷贝构造函数。如果你有一个std::string成员,你就没有一个no-throw-copy构造函数。如果系统无法复制你的异常,它将终止你的程序。 在设计异常类型层次结构时使用虚拟继承也是一个好主意,如中所述 http://www.boost.org/doc/libs/release/libs/exception/doc/using_virtual_inheritance_in_exception_types.html . 然而,不要求异常对象简单或不分配内存。事实上,异常对象本身通常是在堆上分配的,因此系统可能会在试图抛出异常时耗尽内存。 |
![]() |
7
0
我认为拒绝在异常类中使用std::string是不必要的纯粹主义。是的,它能扔。那又怎么样?如果std::string的实现抛出 因为内存不足以外的原因 仅仅因为您正在构造一条消息“无法解析文件Foo”,那么实现就有问题,而不是代码。 至于内存不足,即使构造一个不带字符串参数的异常,也会出现这个问题。添加20字节有用的错误消息不太可能成功或失败。在桌面应用程序中,大多数OOM错误发生在你试图错误地分配20GB内存时,这并不是因为你一直在以99.9999%的容量愉快地运行,或者有什么事情让你大吃一惊。 |
![]() |
8
0
不幸的是,这正是大多数人所说的,因为他们不想处理由此产生的复杂性。另一方面,如果您确实遵循了标准设置的要求,您将获得更健壮的软件,即使在内存不足的情况下也可以恢复。 撇开火星漫游者不谈,想想这样一个简单的例子,比如编写一个文本处理器。您希望实现复制/粘贴功能。用户选择一些文本并点击Ctrl+C。您更喜欢哪种结果:崩溃或消息“内存不足”?(如果没有足够的内存来显示消息框,则什么也不会发生。)第二种情况无疑更加用户友好,她可以关闭其他应用程序,继续处理她的文档。 事实上,保证不抛出复制构造函数并不难。您应该只在异常中存储一个指向动态分配内存的共享指针:
假设异常是针对异常情况的,那么原子计数开销可以忽略不计。事实上,这就是提振。例外。 话虽如此,我还是推荐jalf的答案。 |
![]() |
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
![]() |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
![]() |
rainer · 后台插入程序的初始化 1 年前 |
![]() |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
|
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
|
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |