C++ RAII 教程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2635882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:10:19  来源:igfitidea点击:

RAII tutorial for C++

c++raii

提问by Joe Bloggs

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.

我想学习如何在 C++ 中使用 RAII。我想我知道它是什么,但不知道如何在我的程序中实现它。快速谷歌搜索没有显示任何不错的教程。

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

有没有人有任何好的链接可以教我 RAII?

采纳答案by utnapistim

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."

RAII 可以简单地解释为“每个需要清理的资源都应该提供给对象的构造函数”。

In other words:

换句话说:

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

指针应该封装在智能指针类中(参见 std::auto_ptr、boost::shared_ptr 和 boost::scoped_ptr 示例)。

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).

同步应该依赖于在作用域退出时释放互斥锁/同步原语(参见 boost::mutex::scoped_lock 用法示例)。

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.

我不认为您真的可以拥有关于 RAII 的教程(例如,您无法拥有关于设计模式的教程)。RAII 更像是一种查看资源的方式。

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

例如,目前我正在使用 WinAPI 进行编码,并编写了以下类:

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 Somethinggo out of scope (as Something::~Something-> WindowHandle::WindowHandle-> ::Close(_window._value)).

该成员已分配,但我从不::CloseWindow(_window._handle)明确调用(当实例Something超出范围(如Something::~Something-> WindowHandle::WindowHandle-> ::Close(_window._value))时将调用它。

回答by Goz

The wikipediaexplanation isn't bad.

维基百科的解释是不坏。

回答by Matthew T. Staebler

The reference that I personally have found most helpful on the topic of RAII is the book Exceptional C++by Herb Sutter.

我个人认为对 RAII 主题最有帮助的参考书是 Herb Sutter所著的Exceptional C++一书。

Many of the topics covered in that book are touched on in the Guru of the Week articles by Sutter. Those articles are available at http://gotw.ca/gotw/index.htm.

该书中涵盖的许多主题在 Sutter 的 Guru of the Week 文章中都有涉及。这些文章可在http://gotw.ca/gotw/index.htm 上找到

回答by Chubsdad

Item 13 of "Effective C+"is also pretty useful

“Effective C+”的第 13 条也很有用