Как пройти делетер в make_shared в?

Начиная с C++11, из-за нескольких причин, разработчики стремятся использовать классы смарт-указатель для динамических объектов жизни. И с этих новых классов интеллектуальных указателей, стандарты, даже рекомендовать не использовать операторы, такие как новый вместо этого они предлагают использовать make_shared В " или " make_unique, чтобы избежать некоторых ошибок.

Если мы хотим использовать смарт-указатель класса, как shared_ptr, мы можем построить один, как,

shared_ptr<int> p(new int(12));

Также мы хотели бы передать пользовательским deleter на занятия смарт-указатель,

shared_ptr<int> p(new int(12), deleter);

С другой стороны, если мы хотим использовать make_shared в выделять, напр. инт, вместо того, чтобы использовать новые и `shared_ptr конструктор, как на первом выше выражение, мы можем использовать

auto ip = make_shared<int>(12);

Но что, если мы хотим также передать пользовательским deleter к make_shared в, есть правильный способ сделать это? Похоже, составители, по крайней мере на GCC, выдает ошибку,

auto ip = make_shared<int>(12, deleter);
Комментарии к вопросу (1)
Решение

Как другие сказали, make_shared в не может быть использован с пользовательским deleter. Но я хочу объяснить, почему.

Существует обычай deleters, потому что вы выделили курсором в какой-то особый путь, и поэтому вы должны быть в состоянии освободить ее, соответственно, особый путь. Ну, make_shared в` выделяет указатель с "новой". Объекты, выделенные с "новой", должна быть освобождена с "удалить". Какой стандарт Нижнего послушно делает.

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

Кроме того, make_shared в разрешено (и почти наверняка) выделить память для T и блок управления для shared_ptr в то же распределение. Это то, что ваш делетер может'т действительно знаю о или заниматься. В то время как allocate_shared способен работать, поскольку распределителя вы предоставляете можете сделать выделение и освобождение обязанностей.

Комментарии (9)

Как и в документации, make_shared в принимает список аргументов, с которым экземпляр Т будет построен*.<БР/> Кроме того, в документации сказано, что:

эта функция обычно используется, чтобы заменить конструкции с std::shared_ptr и л;т>(Т(аргументы...)) общий указатель на исходный указатель, возвращаемый вызовом нового.

Из-за этого, можно сделать вывод, что вы можете'т установить пользовательский Стиратель.<БР/> Чтобы сделать это, вы должны создать shared_ptr для себя посредством права конструктор&.ЛТ;БР/> В качестве примера конструктор из предлагаемого списка, вы можете использовать:

template< class Y, class Deleter > 
shared_ptr( Y* ptr, Deleter d );

Таким образом, код будет что-то вроде:

auto ptr = std::shared_ptr(new MyClass{arg1, arg2}, myDeleter);

Вместо:

auto ptr = std::make_shared(arg1, arg2);
Комментарии (0)

Вы можете'т. make_shared в<П> направляет аргументы в конструктор типа "Т". Он используется для простого случая, когда вы хотите делетер по умолчанию.

Комментарии (0)

Это является неуказанным, как make_shared вполучает памяти для объекта (его может использовать оператор new или функции malloc или какой-то распределитель) так что нет никакого способа пользовательским deleter мог знать, как поступить правильно. make_shared в создает объект, так что вы должны также полагаться на нее, чтобы уничтожить объект правильно и делать соответствующие убирать, что бы это ни было.

также мы хотели бы передать пользовательским deleter на занятия смарт-указатель,

shared_ptr и Л;int> п(новый инт(12), делетер);

Я не'т считаю, что это очень реалистичный пример. Пользовательским deleter обычно используется, когда ресурс был получен каким-то особым образом. Если вы только что создали с "новым", как это, то зачем тебе пользовательским deleter в любом случае?

Если вы просто хотите, чтобы некоторый код будет работать на уничтожение затем положить его в деструктор! Таким образом, вы также можете использовать его с make_shared в например

struct RunSomethingOnDestruction {
  RunSomethingOnDestruction(int n) : i(n) { }
  ~RunSomethingOnDestruction() { /* something */ }
  int i;
};

auto px = std::make_shared(12);
std:shared_ptr p(px, px->i);

Это дает вам shared_ptr и Л;int>, созданный make_shared в (так что вы получите оптимизаций памяти сделано make_shared в), Что может запустить пользовательский код на уничтожение.

Комментарии (0)

Если вы используете пользовательским deleter вы можете'т использовать make_unique илиmake_shared в функции при создании объектов смарт-указатель . Поскольку мы должны предоставить нашим пользовательским deleter эти функции не поддерживают это .

Дон'т использовать make_unique или make_shared в Если вам нужна пользовательским deleter или применяя исходный указатель из других стран.

По идее если вам нужен специализированный способ удалить ваш объект, вы, вероятно, нужно особым образом, чтобы создать их .

Пусть говорят, что мы тест класс


#include     
using namespace std;    
class Test
{
private : 
    int data; 
    public : 
    Test() :data{0}
    {
        cout 
Комментарии (0)