zoukankan      html  css  js  c++  java
  • 条款08:别让异常逃离析构函数

    问题:如果一个类的析构函数必须执行一个动作,而该动作可能会在失败时抛出异常,该怎么办?举个例子,假设使用过一个class负责数据库连接:

    class DBConnection
    {
    public:
    	...
    	static DBConnection create();	//此函数返回DBConnection对象
    
    	void close();			//关闭联机;失败则抛出异常
    };
    

    一个较佳策略是创建一个用来管理DBConnection资源的DBConn类,DBConn类自己提供一个close函数,因而赋予客户一个机会得益处理“因该操作而发生的异常”。DBConn也可以追踪其所管理的DBConnection是否已被关闭,若没有被关闭,则由DBConn的析构函数关闭它。这可防止遗失数据连接。然而如果DBConnection析构函数调用close失败,则可使用“强制结束程序”或“吞下异常”的方法:

    class DBConn
    {
    public:
    	DBConn();
    	~DBConn();
    
    	void close();
    private:
    	DBConnection db;
    	bool closed;
    };
    
    DBConn::DBConn()
    {
    }
    
    DBConn::~DBConn()
    {
    	if(!closed)
    	{
    		try
    		{
    			db.close();          //关闭连接
    		}
    		catch(...)                //如果关闭动作失败
    		{
    			写日志,记下对close的调用失败;  //记录下来并结束程序
    			...                //或者吞下异常;
    		}
    	}
    }
    
    void DBConn::close()		//供客户使用的新函数
    {
    	db.close();
    	closed = true;
    }
    

      

    如果某个操作可能在失败时抛出异常,而又存在某种需要必须处理该异常,那么这个异常必须来自析构函数以外的某个函数。因为析构函数抛出异常及时危险,总会带来“过早结束程序”或“发生不明确行为”的风险。

    请牢记:

    1、析构函数绝对不要抛出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕获异常,然后吞下它们或结束程序。

    2、如果客户需要对某个操作函数进行运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行操作。

     

  • 相关阅读:
    PAIRING WORKFLOW MANAGER 1.0 WITH SHAREPOINT 2013
    Education resources from Microsoft
    upgrade to sql server 2012
    ULSViewer sharepoint 2013 log viewer
    Top 10 Most Valuable Microsoft SharePoint 2010 Books
    讨论 Setsockopt选项
    使用 Alchemy 技术编译 C 语言程序为 Flex 可调用的 SWC
    Nagle's algorithm
    Nagle算法 TCP_NODELAY和TCP_CORK
    Design issues Sending small data segments over TCP with Winsock
  • 原文地址:https://www.cnblogs.com/lwenwen/p/3468314.html
Copyright © 2011-2022 走看看