2016-01-20 73 views
-5

我有一个关于try catch机制的问题。类似的代码:关于C++的一些问题try catch

global value default 0; 
    int thread1() 
    { 
     try 
     { 
      set global value to 1; 
      if exception happens 
      { 
       jump into catch; 
      } 
      set global value to 0; 
     } 
     catch 
     { 
      ...... 
     } 
    } 
    int thread2() 
    { 
     ASSERT(global value = 0); 
    } 

如果我有假码如图所示,在try块我一个全局值设置为1,然后一个异常发生时,在线程2我有一个ASSERT以测试是否该全局值等于0,那么thread2将显式失败,因为在thread1中,由于异常我们跳入catch块。那么有人可以给我一些解释吗?我不知道如何尝试赶上工程,以防止这种情况。

+6

我假设你显示的代码是* pseudo * code?还要注意,在涉及异常和异常处理时,C,C++和C#是完全不同的语言,并且有自己的语义。哎呀,C甚至没有*例外。 –

+0

另请注意,全局值的设置和读操作必须是原子的。 –

+1

即使发生异常,您想知道如何确保某些代码正在运行('global_value = 0;')? [RAII](http://en.cppreference.com/w/cpp/language/raii)。 – BoBTFish

回答

0

例外情况是正常执行流程的残酷破坏。错误更正流程是查找与抛出的对象相对应的catch;这可能导致几个函数调用反向遍历。这就是为什么它需要小心使用它们,你有两个执行流程:正常的和错误的。

如果抛出的异常在catch块之后直接捕获,那么你只需要在catch-block中设置你的变量为0。

不是,一个好的解决方案是RAII(正如评论中所建议的那样)。 RAII是一个非常简单的想法。如你所知,当控制离开块任何块的进入堆栈中创建的每个对象被销毁,这个想法是建立一个封装的东西的对象,这样的析构函数将被调用无论发生什么情况:

class GlobalControl { 
    public: 
    GlobalControl() { myglob = 1; } // RAII 
    ~GlobalControl() { myglob = 0; } // RRID 
}; 

... // somewhere else 
try { 
    GlobalControl c; // ctor call init glob to 1 
    ... 
} // whatever will happens, leaving this block cause a call to dtor of c 
catch (...) { 
} 

RAII代表资源获取是初始化,这里您的资源获取是将您的全局设置为1,并且这是在对象的初始化部分进行的。应该将RAII称为RAIIRRID,RAII +资源释放是破坏性的(资源发布是将您的全局设置为0,并且这是在析构函数中进行的)。