Pertanyaan Tutorial RAII untuk C ++ [tertutup]


Saya ingin belajar cara menggunakan RAII di c ++. Saya pikir saya tahu apa itu, tetapi tidak tahu bagaimana menerapkannya dalam program saya. Pencarian google cepat tidak menunjukkan tutorial yang bagus.

Apakah ada yang punya tautan bagus untuk mengajari saya RAII?


32
2018-04-14 08:25


asal


Jawaban:


Tidak ada apa-apa (artinya, saya tidak berpikir Anda perlu tutorial lengkap).

RAII dapat dijelaskan secara singkat sebagai "Setiap sumber daya yang membutuhkan pembersihan harus diberikan kepada konstruktor objek."

Dengan kata lain:

Pointer harus dienkapsulasi dalam kelas penunjuk pintar (lihat std :: auto_ptr, boost :: shared_ptr dan boost :: scoped_ptr untuk contoh).

Gagang yang membutuhkan pembersihan harus dikemas dalam kelas yang secara otomatis membebaskan / melepaskan pegangan saat penghancuran.

Sinkronisasi harus bergantung pada pelepasan mutex / sinkronisasi primitif setelah keluar dari scope (lihat boost :: mutex :: scoped_lock usage untuk contoh).

Saya tidak berpikir Anda benar-benar dapat memiliki tutorial tentang RAII (tidak lagi daripada Anda dapat memiliki satu pada pola desain misalnya). RAII lebih merupakan cara untuk melihat sumber daya daripada hal lain.

Sebagai contoh, saat ini saya sedang mengkodekan menggunakan WinAPI dan saya menulis kelas berikut:

template<typename H, BOOL _stdcall CloseFunction(H)>
class checked_handle
{
public:
    typedef checked_handle<H,CloseFunction> MyType;
    typedef typename H HandleType;

    static const HandleType     NoValue;

    checked_handle(const HandleType value)
        : _value(value)
    {
    }

    ~checked_handle()
    {
        Close();
    }

    HandleType* operator &()
    {
        return &_value;
    }

    operator HandleType()
    {
        return _value;
    }

private:
    HandleType      _value;

    void Close(const HandleType newValue = NoValue)
    {
        CloseFunction(_value);
        _value = newValue;
    }
};

template<typename H,BOOL _stdcall CloseFunction(H)>
const typename checked_handle<H,CloseFunction>::HandleType 
    checked_handle<H,CloseFunction>::NoValue = 
    checked_handle<H,CloseFunction>::HandleType(INVALID_HANDLE_VALUE);

typedef checked_handle<HANDLE,::CloseHandle> CheckedHandle;
typedef checked_handle<HWINSTA,::CloseWindowStation> WinStationHandle;
typedef checked_handle<HDESK,::CloseDesktop> DesktopHandle;
typedef checked_handle<HDEVNOTIFY,::UnregisterDeviceNotification> DevNotifyHandle;
typedef checked_handle<HWND,::DestroyWindow> WindowHandle;

BOOL __stdcall CloseKey(HKEY hKey);
typedef checked_handle<HKEY,CloseKey> RegHandle;

Kelas ini tidak termasuk tugas dan menyalin semantik (saya menghapusnya untuk memberikan contoh minimal) sehingga kembali dengan nilai, akan menyebabkan gagang ditutup dua kali.

Begini cara penggunaannya:

deklarasi kelas:

class Something
{
public:
    // ...
private:
    WindowHandle        _window;
};

Anggota ini dialokasikan tetapi saya tidak pernah menelepon ::CloseWindow(_window._handle) explicitely (itu akan disebut ketika contoh Something keluar dari ruang lingkup (seperti Something::~Something -> WindowHandle::WindowHandle -> ::Close(_window._value) ).


26
2018-04-14 11:26



Itu wikipedia penjelasannya tidak buruk.


3
2018-04-14 08:28



Referensi yang menurut saya pribadi paling membantu dalam topik RAII adalah buku C ++ luar biasa oleh Herb Sutter.

Banyak topik yang dibahas dalam buku itu disinggung dalam artikel Guru Pekan Ini oleh Sutter. Artikel-artikel itu tersedia di http://gotw.ca/gotw/index.htm.


2
2018-04-14 08:47



Item 13 dari "Efektif C +" juga sangat berguna


2
2017-09-24 05:48