Общий класс ручки

Я наткнулся на эту проблему: Использование unique_ptr для управления дескриптором файла. std::unique_ptr не совсем подходит для общего управления. Так более общий класс

template<class HandleType,HandleType nullvalue,class Deleter>
class Handle;

уже реализовано (может быть, в boost), или я должен свернуть свой собственный. Этот вопрос был поднят ранее в
Какой класс-оболочку в C ++ я должен использовать для автоматического управления ресурсами?, но теперь у нас есть C ++ 14, так что может быть больше альтернатив.

Я также нашел следующее предложение: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3677.html. Так что кто-то еще тоже думал об этой проблеме.

3

Решение

В стандарте 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);
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]