Подтвердить что ты не робот

Есть ли недостатки с использованием make_shared для создания shared_ptr

Есть ли недостатки с использованием make_shared<T>() вместо использования shared_ptr<T>(new T).

Boost documentation утверждает

Повторялись запросы от пользователей для функции factory, которая создает объект определенного типа и возвращает shared_ptr к нему. Кроме удобство и стиль, такая функция также является безопасным исключением и значительно быстрее, потому что он может использовать единое распределение как для объект и соответствующий ему контроль блока, устраняя значительный часть конструкции shared_ptr накладные расходы. Это устраняет один из жалобы о большой эффективности shared_ptr.

4b9b3361

Ответ 1

Я знаю как минимум два.

  • Вы должны контролировать распределение. Не очень большой, но некоторые старые api любят возвращать указатели, которые вы должны удалить.
  • Никакой пользовательский дебетер. Я не знаю, почему это не поддерживается, но это не так. Это означает, что ваши общие указатели должны использовать детонатор ванили.

Довольно слабые места. поэтому старайтесь всегда использовать make_shared.

Ответ 2

В дополнение к точкам, представленным @deft_code, еще более слабый:

  • Если вы используете weak_ptr, которые живут после того, как все shared_ptr к данному объекту умерли, тогда память этого объекта будет находиться в памяти вместе с блоком управления до тех пор, пока не исчезнет последний слабый_ptr. Другими словами, объект уничтожается, но не освобождается до тех пор, пока не будет уничтожен последний weak_ptr.

Ответ 3

От http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/

Другим недостатком реализации make_shared() является увеличение размера объектного кода. Благодаря тому, как эта оптимизация будет реализована, будет создана дополнительная виртуальная таблица, а также набор виртуальных функций для каждого типа объекта, который вы используете с make_shared().

Ответ 4

Кроме того, make_shared не совместим с шаблоном factory. Это связано с тем, что вызов make_shared внутри вашей функции factory вызывает код библиотеки, который, в свою очередь, вызывает new, к которому у него нет доступа, , поскольку он не может вызвать частный конструктор класса (s ) (конструктор должен быть закрытым, если вы правильно следуете шаблону factory).

Ответ 5

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

Если это необходимо, используйте std::allocate_shared<T> вместо этого:

std::vector<std::shared_ptr<std::string>> avec; 
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));

Обратите внимание, что вектор не должен быть проинформирован о распределителе!

Для создания настраиваемого распределителя посмотрите здесь fooobar.com/info/105492/...