我经常看到/听到人们说异常应该很少使用,但永远不解释原因.虽然这可能是真的,但理由通常是一种愚蠢:"它被称为例外的原因",对我来说,这似乎是一种不应被一位受人尊敬的程序员/工程师接受的解释.
可以使用异常来解决一系列问题.为什么将它们用于控制流程是不明智的?对它们的使用方式保持格外保守的理念是什么?语义?性能?复杂?美学?惯例?
我之前已经看过一些关于性能的分析,但是在与某些系统相关且与其他系统无关的水平上.
同样,我不一定不同意他们应该在特殊情况下得救,但我想知道共识的理由是什么(如果这样的事情存在的话).
我的理解是,普遍的智慧说只使用异常才能获得真正特殊的条件(事实上,我已经多次在SO上看到过这种说法).
然而,Krzysztof Cwalina说:
关于例外的最大误解之一是它们用于"特殊条件".现实情况是它们用于传达错误条件.从框架设计的角度来看,没有"特殊条件"这样的东西.条件是否异常取决于使用的上下文,但可重用的库很少知道如何使用它们.例如,对于简单的数据输入应用程序,OutOfMemoryException可能是例外; 对于进行自己的内存管理的应用程序(例如SQL服务器)来说,这并不是那么特别.换句话说,一个人的特殊情况是另一个男人的慢性病.
然后,他接着说,例外情况应该用于:
考虑到Krzysztof Cwalina是MS CLR团队的PM,我问:你如何看待他的陈述?
处理异常涉及很多相对性.除了低级别的API,其中异常包括从硬件和操作系统引发的错误,有一个阴暗的区域,程序员决定什么构成异常,什么是正常情况.
你如何决定何时使用例外?您是否有关于例外的一致政策?
我正在阅读谷歌C++风格指南,并在例外部分感到困惑.根据指南,使用它的一个缺点是:
异常安全需要RAII和不同的编码实践.需要大量的支持机制才能使编写正确的异常安全代码变得容易.此外,为了避免要求读者理解整个调用图,异常安全代码必须将写入持久状态的逻辑隔离到"提交"阶段.这将带来好处和成本(可能是您被迫混淆代码以隔离提交的地方).允许例外将迫使我们总是支付这些费用,即使它们不值得
具体来说,我不明白的陈述是这样的:
(...)异常安全代码必须将写入持久状态的逻辑隔离到"提交"阶段.
还有这个:
(...)也许你被迫混淆代码来隔离提交(...).
我想我不习惯术语"持久状态","提交阶段","混淆代码以隔离提交".关于这些术语的一些小解释,例子或参考可能是很好的,也可能是为什么这是真的.
无法弄清楚如何准确地说出问题,所以这是一个例子:
鉴于此功能原型:
void Foo(myClass* bar);
Run Code Online (Sandbox Code Playgroud)
我想阻止这种用法:
Foo(new myClass());
Run Code Online (Sandbox Code Playgroud)
而是需要先前创建的对象:
myClass* bar = NULL;
bar = new myClass();
Foo(bar);
Run Code Online (Sandbox Code Playgroud)
要么
myClass bar;
Foo(&bar);
Run Code Online (Sandbox Code Playgroud)
谢谢.
这是一个澄清的例子:
void Mouse::SetImage(BITMAP* image, int focusX, int focusY) {
if(_image) {
set_mouse_sprite(NULL);
set_mouse_sprite_focus(0, 0);
show_mouse(NULL);
destroy_bitmap(_image);
_image = NULL;
}
if(image) {
_image = create_bitmap(image->w, image->h);
clear_bitmap(_image);
blit(image, _image, 0, 0, 0, 0, image->w, image->h);
}
if(image == NULL) {
focusX = 0;
focusY = 0;
}
_focusX = focusX;
_focusY = …Run Code Online (Sandbox Code Playgroud)