这就是我要做的事情(这是对真实项目的简化):
int param;
int result;
void isolated(int p) {
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
} catch (...) {
throw "problems..";
}
}
我无法改变process()
的工作方式,因为此功能不是在项目中创建的,而是第三方功能。它适用于全局变量param
和result
,我们无法改变它。
从isolated()
使用其他参数调用process()
时,会出现问题。我想抓住这种情况,但不知道该怎么做,因为在C ++中没有finally
。我觉得我应该使用RAII技术,但在这种情况下无法弄清楚如何正确地做到这一点。
我可以通过代码复制实现这一目标:
int param;
int result;
void isolated(int p) {
static bool running;
if (running) {
throw "you can't call isolated() from itself!";
}
running = true;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
running = false;
} catch (...) {
running = false; // duplication!
throw "problems..";
}
}
答案 0 :(得分:5)
“finally”喜欢在C ++中使用保护对象处理情境,这些对象最终在析构函数中执行。这是IMHO更强大的方法,因为您必须分析情况以最终确定以创建可重用的对象。在这种情况下,我们需要使进程租用,因为参数和返回在全局变量中传递。解决方案是在输入时保存它们的值并在退出时恢复它们:
template<class T>
class restorer
{
T &var; // this is the variable we want to save/restore
T old_value; // the old value
restorer(const restorer&);
void operator=(const restorer&);
public:
restorer(T &v) : var(v), old_value(v) {}
~restorer() { var=old_value; }
};
int param;
int result;
int isolated(int p) {
restorer<int> rest_param(param);
restorer<int> rest_result(result);
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
答案 1 :(得分:2)
也许我没弄错,但你为什么不用旗?你想知道何时从process()调用isolated(),对吧?
int isolated(int p) {
static int execDeep = 0;
execDeep++;
// your code here
execDeep--;
}
现在您可以检查'execDeep'值,&gt; 1表示在执行过程中从进程()调用它。
答案 2 :(得分:1)
我仍然不太确定finally
在这里是如何相关的,但如果您想避免自己创建范围保护结构,可以尝试Boost.ScopeExit。
示例:
#include <boost/scope_exit.hpp>
#include <cstdio>
int isolated(int p) {
static bool running = false;
if (running) {
printf("Throwing %d\n", p);
throw p;
}
printf("Starting %d\n", p);
running = true;
BOOST_SCOPE_EXIT( (p)(&running) ) { // <--
printf("Stopping %d\n", p); // <--
running = false; // <--
} BOOST_SCOPE_EXIT_END // <--
// ...
if (p)
isolated(p*10);
// ...
printf("Returing %d\n", p);
return 4;
}
int main() {
printf(">> first\n");
isolated(0);
printf(">> second\n");
try {
isolated(1);
printf(">> third (should not be printed.)\n");
} catch(int p) {
printf("Caught %d\n", p);
}
isolated(0);
printf(">> fourth\n");
return 0;
}
结果:
>> first Starting 0 Returing 0 Stopping 0 >> second Starting 1 Throwing 10 Stopping 1 Caught 10 Starting 0 Returing 0 Stopping 0 >> fourth
答案 3 :(得分:0)
这可行吗?
int save = -10000000000;
int param;
int result;
int isolated(int p) {
if (save != -10000000000)
{
// run the other condition
}
else
{
save = p;
param = p;
try {
// make calculations with "param" and place the
// result into "result"
process();
return result;
} catch (...) {
return 0;
}
}
}
答案 4 :(得分:0)
如果我理解正确,您希望在功能结束时自动将运行标志设置为false。如果这是要求,那么您可以使用链接中提到的ScopeGuard赞成。