Effective C++ Item 8 Prevent exception from leaving destructors

Throw an exception in destructor is dangerous and you should never let exception escape from destructor. If there are two more exceptions propagating, the program will teminated or yield undefined behavior. Consider the example

#include <iostream>
class Bad
{
    public:
        ~Bad()
        {
            std::cout << "Throw in ~Bad()." << std::endl;
            throw 1;
        }
};
int main()
{
    try
    {
        Bad   bad;
    }
    catch(...)
    {
        std::cout << "Print This" << std::endl;
    }
    try
    {
        Bad   bad;
        std::cout << "Throw in other place." << std::endl;
        throw 2;
    }
    catch(...)
    {
        std::cout << "Never print this " << std::endl;
    }
}

The output would be like this

Throw in ~Bad().
Print This
Throw in other place.
Throw in ~Bad().
terminate called after throwing an instance of ‘int‘
bash: line 1:  4318 Aborted                 (core dumped) ‘/home/sangs/Documents/singleton‘
[Finished in 0.8s with exit code 134]

Notice that the exception would progagate in the program and when two exceptions occurs, the program would terminated or lead to undefined behaviors.

 

What should we do if we have to throw an exception in desturctor?

Consider we have a class to handle Dbconnection and has a close method to close the connection. It will throw exception in close if close fails.

class DBConnection {
public:
    ...
    static DBConnection create();
    void close(); // it will throw an exception
};

  

To ensure that client won‘t forget close the DB connection, we have a resource management class to handle that. Specifically, we call close method in Dbcon‘s destructor function

class DBConnection {
public:
    ...
    ~DBConnection() {
        db.close();
    }
private:
    DBConnection db;
};

 

But here, we allow exception propagate out the destructor which is dangerous as we discussed previously. So, what‘s solution? We can catch the exception in the destructor and swallow the exception or terminate the program. This method is better than let the program goes into undefined situation, but it is not best either.

What we should do is providing a close function to clients to give them opportunity handle exception themselves and swallow the exception in destructor if client fail to hanle exceptions

class DBConnection {
public:
    ...
    void close() {
        db.close();
        closed = true;
    }
 
    ~DBConnection() {
        if(!closed) {
            db.close();
        }
        catch(...) {
            // swallow the exception
        }
    }
private:
    DBConnection db;
};

  

Effective C++ Item 8 Prevent exception from leaving destructors,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。