Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RAII tutorial for C++ [closed]

Tags:

c++

raii

I'd like to learn how to use RAII in c++. I think I know what it is, but have no idea how to implement it in my programs. A quick google search did not show any nice tutorials.

Does any one have any nice links to teach me RAII?

like image 922
Joe Bloggs Avatar asked Apr 14 '10 08:04

Joe Bloggs


2 Answers

There's nothing to it (that is, I don't think you need a full tutorial).

RAII can be shortly explained as "Every resource requiring cleanup should be given to an object's constructor."

In other words:

Pointers should be encapsulated in smart pointer classes (see std::auto_ptr, boost::shared_ptr and boost::scoped_ptr for examples).

Handles requiring cleanup should be encapsulated in classes that automatically free/release the handles upon destruction.

Synchronization should rely on releasing the mutex/synchronization primitive upon scope exit (see boost::mutex::scoped_lock usage for an example).

I don't think you can really have a tutorial on RAII (not anymore than you can have one on design patterns for example). RAII is more of a way of looking at resources than anything else.

For example, at the moment I'm coding using WinAPI and I wrote the following class:

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; 

This class doesn't include assignment and copy semantics (I removed them to provide a minimal example) so returning by value, will cause the handles to be closed twice.

Here's how it's used:

class declaration:

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

This member is allocated but I never call ::CloseWindow(_window._handle) explicitely (it will be called when instances of Something go out of scope (as Something::~Something -> WindowHandle::WindowHandle -> ::Close(_window._value) ).

like image 71
utnapistim Avatar answered Oct 05 '22 23:10

utnapistim


The wikipedia explanation isn't bad.

like image 25
Goz Avatar answered Oct 05 '22 23:10

Goz