Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104563571
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: C/C++

2008-04-15 18:44:07

    来源:IBM    作者:Sachin O. Agrawal

管理构造函数和析构函数中的异常

在全局(静态全局)变量的构造和析构期间,每个ANSI C++ 都捕获到异常是不可能的。因此,ANSI C++ 不建议在那些其实例可能被定义为全局实例(静态全局实例)的类的构造函数和析构函数中抛出异常。换一种说法就是永远都不要为那些其构造函数和析构函数可能抛出异常的类定义全局(静态全局)实例。不过,如果假定有一个特定编译器和一个特定系统,那么可能可以这样做,幸运的是,对于 Linux 上的 GCC,恰好是这种情况。

使用ExceptionHandler类可以展示这一点,该类也采用了singleton设计模式。其构造函数注册了一个未捕获的处理程序。因为每次只能有一个未捕获的处理程序处理一个活动进程,构造函数应该只被调用一次,因此要采用singleton模式。应该在定义有问题的实际全局(静态全局)变量之前定义ExceptionHandler 的全局(静态全局)实例。

清单 3. 处理构造函数中的异常

class ExceptionHandler
 {
 private:
     class SingleTonHandler
     {
     public:
         SingleTonHandler()
         {
             set_terminate(Handler);
         }

         static void Handler()
         {
             // Exception from construction/destruction of global variables
             try
             {
                 // re-throw
                 throw;
             }
             catch (SegmentationFault &)
             {
                 cout << "SegmentationFault" << endl;
             }
             catch (FloatingPointException &)
             {
                 cout << "FloatingPointException" << endl;
             }
             catch (...)
             {
                 cout << "Unknown Exception" << endl;
             }

             //if this is a thread performing some core activity
             abort();
             // else if this is a thread used to service requests
             // pthread_exit();
         }
     };

 public:
     ExceptionHandler()
     {
         static SingleTonHandler s_objHandler;
     }
 };

 //////////////////////////////////////////////////////////////////////////

 class A
 {
 public:
     A()
     {
         //int i = 0, j = 1/i;
         *(int *)0 = 0;
     }
 };

 // Before defining any global variable, we define a dummy instance
 // of ExceptionHandler object to make sure that
 // ExceptionHandler::SingleTonHandler::SingleTonHandler() is invoked
 ExceptionHandler g_objExceptionHandler;
 A g_a;

 //////////////////////////////////////////////////////////////////////////

 int main(int argc, char* argv[])
 {
     return 0;
 }

处理多线程程序中的异常

有时一些异常没有被捕获,这将造成进程异常中止。不过很多时候,进程包含多个线程,其中少数线程执行核心应用程序逻辑,同时,其余线程为外部请求提供服务。如果服务线程因编程错误而没有处理某个异常,则会造成整个应用程序崩溃。这一点可能是不受人们欢迎的,因为它会通过向应用程序传送不合法的请求而助长拒绝服务攻击。为了避免这一点,未捕获处理程序可以决定是请求异常中止调用,还是请求线程退出调用。清单 3 中 ExceptionHandler::SingleTonHandler::Handler() 函数的末尾处展示了该处理程序。

结束语

我简单地讨论了少许 C++ 编程设计模式,以便更好地执行以下任务:

在抛出异常的时候追踪异常的来源。

将信号从内核程序转换成 C++ 异常。

捕获构造和/或析构全局变量期间抛出的异常。

多线程进程中的异常处理。

我希望您能采用这些技巧中的一些来开发无忧代码。

阅读(324) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~