Does C++ support 'finally' blocks? (And what's this 'RAII' I keep hearing about?)

前端 未结 16 1561
情深已故
情深已故 2020-11-22 17:15

Does C++ support \'finally\' blocks?

What is the RAII idiom?

What is the difference between C++\'s RAII idiom and C#\'s \'using\' statement?

16条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-22 17:34

    In C++ the finally is NOT required because of RAII.

    RAII moves the responsibility of exception safety from the user of the object to the designer (and implementer) of the object. I would argue this is the correct place as you then only need to get exception safety correct once (in the design/implementation). By using finally you need to get exception safety correct every time you use an object.

    Also IMO the code looks neater (see below).

    Example:

    A database object. To make sure the DB connection is used it must be opened and closed. By using RAII this can be done in the constructor/destructor.

    C++ Like RAII

    void someFunc()
    {
        DB    db("DBDesciptionString");
        // Use the db object.
    
    } // db goes out of scope and destructor closes the connection.
      // This happens even in the presence of exceptions.
    

    The use of RAII makes using a DB object correctly very easy. The DB object will correctly close itself by the use of a destructor no matter how we try and abuse it.

    Java Like Finally

    void someFunc()
    {
        DB      db = new DB("DBDesciptionString");
        try
        {
            // Use the db object.
        }
        finally
        {
            // Can not rely on finaliser.
            // So we must explicitly close the connection.
            try
            {
                db.close();
            }
            catch(Throwable e)
            {
               /* Ignore */
               // Make sure not to throw exception if one is already propagating.
            }
        }
    }
    

    When using finally the correct use of the object is delegated to the user of the object. i.e. It is the responsibility of the object user to correctly to explicitly close the DB connection. Now you could argue that this can be done in the finaliser, but resources may have limited availability or other constraints and thus you generally do want to control the release of the object and not rely on the non deterministic behavior of the garbage collector.

    Also this is a simple example.
    When you have multiple resources that need to be released the code can get complicated.

    A more detailed analysis can be found here: http://accu.org/index.php/journals/236

提交回复
热议问题