2017-01-19 4 views
0

Возможно ли использовать как пользовательский распределитель, так и пользовательский деактивировать в течение std::shared_ptr? Мне кажется, что нет никакого способа сделать это, так как std::allocate_shared не принимает дебетер. И также, единственная разумная подпись делетера была бы чем-то вроде void deleter(T*, const Alloc&), а не только void deleter(T*).shared_ptr пользовательский распределитель вместе с пользовательским удалением

Есть ли способ обойти это ограничение?

ответ

2

Да, вы можете это сделать, но убедитесь, что вы понимаете, что происходит. Цель уничтожителя - уничтожить объект. Распределитель используется для внутренних бухгалтерских структур.

std::shared_ptr<T> sp(new T(args...), std::default_delete<T>(), myalloc); 

Точка make_shared и allocate_shared является то, что они заботиться о создании объекта для вас, так что вы не указали Deleter — они используют свой собственный Deleter, который подходит для пути они получили ресурсы (т.е. соответственно через operator new и предоставленный распределитель).

Вы, конечно, можете создать свой собственный распределитель Deleter (как this one или один proposed here), чтобы перейти в вышеприведенном конструктор, чтобы идти вместе с распределителем распределённой объекта, а затем использовать аллокатор (или другой!) для бухгалтерского учета.

Есть что сказать, что не используется make_shared/allocate_shared в ситуациях, когда у вас есть долгоживущие слабые указатели или где размер двоичных объектов имеет значение.

1

Вы можете использовать отдельный распределитель и деблокировать; есть shared_ptr конструкторы, которые берут оба.

Но вы не можете сделать это через allocate_shared. Причина заключается в том, что распределитель предназначен для распределения/освобождения общего хранилища. Делектор предназначен для уничтожения управляемого объекта и освобождения его хранилища.

Поскольку allocate_shared выделяет объект управляется в же хранении как сам общего хранилище, он больше не имеет смысла для две операции, чтобы быть разделена. И поэтому вы должны использовать один и тот же объект для обоих процессов. Распределитель выделяет и освобождает одно распределение, и он заботится о пошлинах на строительство/уничтожение для создаваемого и уничтоженного T.