управление необработанной памятью с помощью std :: unique_ptr в переполнении стека

Я хочу иметь небольшой класс, который управляет сырой памятью с этим API

template<class allocator = std::allocator<char> >
class raw_memory
{
static_assert(std::is_same<char, typename allocator::value_type>::value,
"raw_memory: allocator must deal in char");
public:
raw_memory() = default;
raw_memory(raw_memory&&) = default;
raw_memory&operator=(raw_memory&&) = default;
explicit raw_memory(size_t, allocator const& = allocator());
~raw_memory();       // deletes any memory
char*get();          // returns pter to (begin of) memory
void resize(size_t); // re-allocates if necessary, may delete old data
size_t size() const; // returns number of bytes currently hold

raw_memory(raw_memory const&) = delete;
raw_memory&operator=(raw_memory const&) = delete;
raw_memory(raw_memory&) = delete;
raw_memory&operator=(raw_memory&) = delete;
};

Параметр шаблона allocator допускает различные варианты выравнивания памяти.

Я думал об использовании std::unique_ptr<char, Deleter>в качестве члена (или базы) (плюс size_t удерживая количество байтов). Что использовать в качестве Deleter? Или есть лучший способ достичь всего этого?

0

Решение

Поскольку вы позволяете пользователям вашего класса указывать распределитель в качестве аргумента типа, вы должны ссылаться на этот аргумент для и то и другое распределение и освобождение. По этой причине комментарий, сделанный @Kerrek (хотя хитрое и приятное использование указателя на функцию) недопустим, потому что вы действительно хотите использовать методы распределителя, переданные в качестве аргумента.

Использование unique_ptr может работать для вас. Как вы правильно прокомментировали, вы должны предоставить свой собственный удалитель, и, согласно моим комментариям выше, он должен основываться на классе распределителя, передаваемом в качестве дополнения к вашему шаблону.

ПОБОЧНОЕ ПРИМЕЧАНИЕ: Пожалуйста, имейте в виду, что в объявлении шаблона есть синтаксическая ошибка. См. Мой пример кода ниже для правильного синтаксиса (то есть у вас должно быть ключевое слово ‘template’):

template< class A = std::allocator<char> >
class raw_memory
{
private:
A m_al;
std::unique_ptr< char, std::function<void(char*)> > m_buffer;

public:
raw_memory( size_t size, const A& al = A() )
:m_al(al)
,m_buffer( m_al.allocate(size), [this, size](char* ptr){ m_al.deallocate(ptr,size); } )
{
}
};

Несколько вещей, чтобы отметить:

  • Я использую A в качестве аргумента типа (я нахожу более читабельным использовать все заглавные буквы для аргумента tymplate).
  • Используя лямбда-нотацию c ++ 11, я передаю функтор удаления конструктору unique_ptr. Этот функтор имеет закрывающее состояние (ссылка на al и размер), которое будет использоваться при удалении. В закрытии я помещаю указатель this (необходим для доступа к m_al) и размер — оба по значению.
2

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

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

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