通用手柄类



我偶然发现了这个问题:使用unique_ptr来控制文件描述符。std::unique_ptr并不真正适合一般手柄。因此,更通用的班级

也是如此
template<class HandleType,HandleType nullvalue,class Deleter>
class Handle;

已经实现(也许是在提升),或者我应该自己滚动。这个问题之前已经提出了我应该在C 中使用哪些包装类别来进行自动化资源管理?

我还找到了以下建议:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3677.html。因此,其他人也考虑了这个问题。

C 标准中还没有这样的类,所以我决定写自己的:

template<typename Policy>
class unique_handle
{
    typename Policy::handle_type h;
public:
    unique_handle(const unique_handle&) = delete;
    typename Policy::handle_type get() const
    {
        return h;
    }
    typename Policy::handle_type release()
    {
        typename Policy::handle_type temp = h;
        h = Policy::get_null();
        return temp;
    }
    explicit operator bool() const
    {
        return !Policy::is_null(h);
    }
    bool operator!() const
    {
        return !static_cast<bool>(*this);
    }
    void reset(typename Policy::handle_type new_handle)
    {
        typename Policy::handle_type old_handle = h;
        h = new_handle;
        if(!Policy::is_null(old_handle))
        {
            Policy::close(old_handle);
        }
    }
    void swap(unique_handle& other)
    {
        std::swap(this->h, other.h);
    }
    void reset()
    {
        reset(Policy::get_null());
    }
    ~unique_handle()
    {
        reset();
    }
    unique_handle& operator=(unique_handle other) noexcept
    {
        this->swap(other);
        return *this;
    }
    unique_handle(unique_handle&& other) noexcept
    {
        this->h = other.h;
        other.h = Policy::get_null();
    }
    unique_handle()
    {
        h = Policy::get_null();
    }
    unique_handle(typename Policy::handle_type handle)
    {
        h = handle;
    }
};

示例用法:

#include <wiertlo/unique_handle.hpp>
#include <iostream>
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
struct file_descriptor_policy
{
    typedef int handle_type;
    static void close(handle_type handle)
    {
        ::close(handle);
    }
    static handle_type get_null()
    {
        return -1;
    }
    static bool is_null(handle_type handle)
    {
        return handle == -1;
    }
};
int main()
{
    typedef wiertlo::unique_handle<file_descriptor_policy> file_descriptor;
    file_descriptor null_fd; // null file descriptor
    assert(!null_fd);
    file_descriptor fd(open("/dev/null", O_WRONLY));
    assert(fd);
    write(fd.get(), "test", 4);
    file_descriptor other = std::move(fd);
    assert(!fd);
    assert(other);
}

相关内容

  • 没有找到相关文章

最新更新