通过_local_ RAII对象释放资源

时间:2014-06-11 04:35:41

标签: c++ c++11 local raii

我完全不了解RAII类的使用以确保资源被释放,但以下示例似乎表明RAII类的本地对象无需能够程序崩溃时释放其资源:

// Compiled via command:
//    /c/opt/mingw64/bin/x86_64-w64-mingw32-g++.exe -D_WIN64 -Wall -Wextra -Werror -std=c++11 -O3 -static-libgcc -static-libstdc++ local_raii.cc -o local_raii.exe
#include <fstream>
#include <iostream>
#include <thread>
#include <mutex>

class some_raii
{
    public:
        some_raii( int i,  const char *message ) : which_one(i)
        {
            std::unique_lock<std::mutex> mu_lock( mu );
            of() << "Started "
                 << which_one
                 << " " 
                 << message
                 << "\n";
            of().flush();
        }
       ~some_raii()
       {
            std::unique_lock<std::mutex> mu_lock( mu );
            of() << "Done with "
                 << which_one
                 << "\n";
            of().flush();
       }

       static std::ofstream& of();
       static std::mutex     mu;

       int which_one{0};
};

std::ofstream& some_raii::of()
{
    static std::ofstream a_of( "output.txt" );
    return a_of;
}

std::mutex   some_raii::mu;

some_raii  globals_destructor_is_called( 100,  "" );

int main()
{
    some_raii locals_destructor_is_NOT_called( 201,  "destructor will not be called -- where's the resource release via RAII?" );

    {
        some_raii fhoo( 301,  "" );
    }

    std::chrono::milliseconds interval( 500 );

    std::cout << "press CTRL-C to terminate this program ...\n"
              << std::flush;
    while(1)
    {
        static int i = 400;
        some_raii fgoo( i++,  "where's the resource release via RAII for the _last_ one?" );
        std::this_thread::sleep_for( interval );
    };

    std::cout << "This line will not be seen\n" << std::flush;

    return 0;
}

从上述一个项目的输出中可以看出:

Started 100
Started 201 destructor will not be called -- where's the resource release via RAII?
Started 301
Done with 301
Started 400 where's the resource release via RAII for the _last_ one?
Done with 400
Started 401 where's the resource release via RAII for the _last_ one?
Done with 401
Started 402 where's the resource release via RAII for the _last_ one?
Done with 100

当程序崩溃时,不需要调用本地RAII对象的析构函数。因此,如果这个RAII对象在其构造函数中打开了一些硬件,那么该硬件将不会被关闭(因为它的析构函数永远不会被执行)。

问题:C ++ 11标准是否提供了一些机制来允许使用本地RAII对象来管理资源,例如打开和关闭某些硬件?如果它没有那么,既然Bjarne Stroustrup推广使用RAII类,为什么他对这里所示的行为没问题呢?

0 个答案:

没有答案