"Effective C + +" study notes-clause 08

Source: Internet
Author: User

*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************


Ii. Constructors,destructors and Assignment Operators


Rule 08:prevent exceptions from leaving destructors

Rule 08: Don't let exceptions escape destructors



1. Talk about a C + + nasty thing

C + + does not prohibit the destructor from spitting out the exception, but it does not encourage you to do so.

First, look at the following example:

Class Widget  {public:    ...    ~widget ()  {...}  Suppose the anomaly};void dosomething () {std::vector<widget> v) may be spit out here    ;    ...}                        V is destroyed here.

When Vector v is destroyed, it destroys all widgets. Add V has 10 widgets, when the first widget is destroyed, an exception is thrown, Ok, there are nine to destroy, and when the second one is destroyed, another exception is thrown. The amount ... This is a bit more for C + +. In the case of two exceptions, if the program is not finished, it leads to ambiguous behavior. So,c++ does not like the destructor to spit out the exception.



2. Even if you know C + + annoying, but we can't avoid to face it

What if a destructor must perform an action, but this action can cause an exception?

Still use the example in the book, with a class to be responsible for database connection:

Class DBConnection  {public:    ...    Static DBConnection Create ();    void close ();};

But in order to ensure that the customer does not forget to call Close () on the DBConnection object, a reasonable idea is to create a class to manage the DBConnection resource and call Close in its destructor, as in the following:

Class Dbconn  {public:    ...    ~dbconn ()    {        db.close ();    } Private:    DBConnection db;};

But this will allow the user to write code like this:

{    dbconn DBC (Dbconnection::create ());    ...} <span style= "White-space:pre" ></span>//the Dbconn object is destroyed at the end of the block because close is automatically called for the DbConnection object

This is a big problem, as long as the call succeeds, it is all good, if the call causes an exception, it will cause the exception to propagate, which is quite bad.

There are two solutions to this situation:

<1>plan01:

If close throws an exception, the program ends. This is usually done by calling Abort:

Dbconn::~dbconn () {    try{db.close ();}    catch (...)  {<span style= "font-family:arial, Helvetica, Sans-serif;" >    </span>
<pre name= "code" class= "CPP" >      production operation record, note that the call to close failed;
Std::abort (); }}


In case of an exception, the program is forced to terminate. After all, it can prevent exceptions from being propagated out of destructors.


<2>PLAN02:

Swallow an exception that occurs because of a call to close

Dbconn::~dbconn () {    try {db.close ();}    catch (...)  {        make a running record, note that the call to close failed;    }}

In general, swallowing an exception is a bad idea because it suppresses important information about "certain actions fail"! However sometimes swallowing abnormalities is also better than "hasty end procedure" or "the risk of ambiguous behavior".



3. A better way?

Both of these methods are not able to respond to situations that cause close to throw an exception.

So, the better way is to redesign the Dbconn interface, for example:

Class Dbconn  {public:    ...    void Close () <span style= "White-space:pre" ></span>//new function    {        db.close () for use by the user;        closed = true;    }    ~dbconn ()    {        if (!closed)  {            try  {<span style= "White-space:pre" ></span>// If the user does not close the connection, perform a close connection                db.close ();            }            Catch  (...)  {<span style= "White-space:pre" ></span>//if the shutdown action failed                to make a running record, write down the call to close failed; ...}}    Private:    DBConnection db;    bool closed;};

This scheme is very easy to understand, set a bool type variable detection, if the user until the end, also did not close the connection, the user closed the connection, otherwise, if the user closed the connection, we do not have to do anything. When the connection is closed, if an exception throws, it can only go back to swallow the abnormal old way, this is how also can not avoid.

The advantages of this scheme, call close responsibility to the user, but also set up a double insurance, make the program more secure.



4. Please remember:

★ Destructors never spit out exceptions. If a function called by a destructor might throw an exception, the destructor should catch any exceptions and swallow them (let them not propagate out) or end the program.

★ If the customer needs to react to an exception that is thrown during the operation of an action function, then class should provide a normal function (rather than a destructor) to perform the operation.



*************************************** Reprint Please specify the Source: Http://blog.csdn.net/lttree ********************************************

"Effective C + +" study notes-clause 08

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.