27 votes

Tutoriel RAII pour C ++

J'aimerais apprendre à utiliser RAII en c ++. Je pense que je sais ce que c'est, mais je n'ai aucune idée de comment le mettre en œuvre dans mes programmes. Une recherche rapide sur Google n'a pas montré de tutoriels intéressants.

Est-ce que quelqu'un a de bons liens pour m'apprendre RAII?

20voto

utnapistim Points 12060

Il n'y a rien pour elle (qui est, je ne pense pas que vous avez besoin d'un tutoriel complet).

RAII peut être peu de temps a expliqué que "Toutes les ressources nécessitant le nettoyage devrait être donnée à un constructeur de l'objet."

En d'autres termes:

Les pointeurs doivent être encapsulées dans des smart pointeur de classes (voir std::auto_ptr, boost::shared_ptr et boost::scoped_ptr pour des exemples).

Poignées nécessitant le nettoyage doit être encapsulé dans des classes automatiquement gratuit/relâchez les poignées à la destruction.

La synchronisation devrait s'appuyer sur la libération du mutex/les primitives de synchronisation lors de l'étendue de sortie (voir boost::mutex::scoped_lock d'utilisation pour un exemple).

Je ne pense pas que vous pouvez vraiment avoir un tutoriel sur RAII (pas plus que vous pouvez vous en avez un sur les modèles de conception par exemple). RAII est plus d'une façon de regarder les ressources qu'autre chose.

Par exemple, en ce moment je suis de codage à l'aide de WinAPI et j'ai écrit la classe suivante:

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;

Cette classe ne comprend pas l'affectation et la sémantique de copie (je l'ai enlevé, pour fournir un exemple minimal) donc pour en revenir à la valeur, sera la cause de la poignée fermée à deux reprises.

Voici comment il est utilisé:

déclaration de la classe:

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

Ce membre est affecté, mais je n'ai jamais appel ::CloseWindow(_window._handle) explicitement (il sera appelé lorsque des instances de l' Something hors de portée (comme Something::~Something -> WindowHandle::WindowHandle -> ::Close(_window._value) ).

3voto

Goz Points 35007

L'explication de wikipedia n'est pas mauvaise.

2voto

La référence que j'ai personnellement trouvée la plus utile sur le sujet du RAII est le livre Exceptional C ++ de Herb Sutter.

Bon nombre des sujets abordés dans ce livre sont abordés dans les articles du gourou de la semaine de Sutter. Ces articles sont disponibles à http://gotw.ca/gotw/index.htm .

2voto

Chubsdad Points 14310

L'article 13 de "C + efficace" est également très utile

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X