这一部分介绍了:
1、使用SEH简化错误处理
2、使用__leave降低开销
Funcarama1
We've pretty much covered the basic syntax and semantics of termination handlers. Now let's look at how a termination handler could be used to simplify a more complicated programming problem. Let's look at a function that doesn't take
advantage of termination handlers at all:
现在我们看一下termination hander如何被用来简化复杂的编程问题,先来看一下根本不用termination hander的情形:
All the error checking in Funcarama1 makes the function difficult to read, which also makes the function difficult to understand, maintain, and modify.
本例中错误处理会比较难读,并因此产生一系列问题。
Funcarama2
Of course, it's possible to rewrite
Funcarama1 so that it is a little cleaner and easier to understand:
看一下这样写是否更易于理解
Although easier to understand than
Funcarama1,
Funcarama2 is still difficult to modify and maintain. Also, the indentation level gets to be pretty extreme as more conditional statements are added; with such a rewrite, you soon end up writing code on the far right of your
screen and wrapping statements after every five characters!
与上个版本相比,有改进但仍不足
Funcarama3
Let's rewrite the first version,
Funcarama1, to take advantage of an SEH termination handler:
使用SEH改写
The real virtue of the Funcarama3 version is that all of the function's cleanup code is localized in one place and one place only: the finally block. If we ever need to add code to this function, we can simply add a single cleanup line in the finally block—we won't have to go back to every possible location of failure and add our cleanup line to each failure location.
本例改进的实质在所有的cleanup代码都在finally中,而不必找所有可能出错的地方增加cleanup代码。Funcarama4: The Final Frontier
The real problem with the Funcarama3 version is the overhead. As I mentioned after the discussion of Funcenstein4, you really should avoid putting return statements into a try block as much as possible.
前一个例子的问题是开销。正如前文所述,应该避免在try中放入return。
To help make such avoidance easier, Microsoft added another keyword,__leave, to its C/C++ compiler. Here is the Funcarama4 version, which takes advantage of the__leave keyword:
微软在编译器里增加了另一个关键字__leave,以下是示例
The use of the __leave keyword in the try block causes a jump to the end of the try block. You can think of it as jumping to the try block's closing brace. Because the flow of control will exit naturally from the try block and enter the finally block, no overhead is incurred. However, it was necessary to introduce a new Boolean variable, bFunctionOk, to indicate the success or failure of the function. That's a relatively small price to pay.
在try中使用__leave使得程序直接跳到try的结尾。因为是自然进入finally,所以没有额外的开销。不过,这里有必要介绍一下新出现的布尔变量bFunctionOk。
When designing your functions to take advantage of termination handlers in this way, remember to initialize all of your resource handles to invalid values before entering your try
block. Then, in the finally block, you can check to see which resources have been allocated successfully so that you'll know which ones to free. Another popular method for tracking
which resources will need to be freed is to set a flag when a resource allocation is successful. Then the code in thefinally block can examine the state of the flag to determine
whether the resource needs freeing
在使用这种方式的时候,要在进入try之前,把所有的资源句柄置为非法值。这样的话,在finally中,你可以检查哪些资源已经被成功申请,以便你知道哪个该被释放。另一种办法是设置表质量。