Есть ли какие-либо недостатки с использованием make shared для создания общего ptr
есть ли какие-либо недостатки с использованием make_shared<T>()
вместо shared_ptr<T>(new T)
.
Boost documentation государства
были повторные запросы от пользователи для заводской функции, которая создает объект заданного типа и возвращает shared_ptr к нему. Кроме того удобство и стиль, такая функция также исключение безопасно и значительно быстрее, потому что он может использовать единое распределение для обоих объект и его соответствующее управление блок, исключающий значительное часть конструкции shared_ptr накладные расходы. Это исключает одно из основные жалобы на эффективность shared_ptr.
5 ответов:
Я знаю по крайней мере двух.
- вы должны контролировать распределение. Не очень большой, но некоторые старые api любят возвращать указатели, которые вы должны удалить.
- нет пользовательским deleter. Я не знаю, почему это не поддерживается, но это не так. Это означает, что ваши общие указатели должна использовать ваниль делетер.
довольно слабые места. поэтому старайтесь всегда использовать make_shared в.
В дополнение к точкам, представленным @deft_code, еще более слабый:
- если вы используете
weak_ptr
s, что жить после того, как всеshared_ptr
s для данного объекта умерли, то память этого объекта будет жить в памяти вместе с блоком управления до последнего weak_ptr умирает. Другими словами объект уничтожается, но не освобождается до последнегоweak_ptr
разрушен.
от http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/
другим недостатком реализации make_shared () является увеличение размера объектного кода. Благодаря тому, как эта оптимизация реализована, для каждого типа объекта, который вы используете с make_shared (), будет создана дополнительная виртуальная таблица, а также набор виртуальных функций.
кроме того,
make_shared
не совместим с заводским шаблоном. Это потому, что вызовmake_shared
внутри вашей заводской функции вызывается код библиотеки, который в свою очередь вызываетnew
, к которому у него нет доступа,так как он не может вызвать частный конструктор(ы) класса (конструктор(ы) должен быть частным, если вы правильно выполните шаблона "фабрика").
С make shared вы не можете указать, как распределение и освобождение из удерживаемого объекта будет сделано.
когда это необходимо, используйте
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!"));
обратите внимание, что вектор не должен быть проинформирован о распределителе!
для создания пользовательского распределителя, посмотрите здесь https://stackoverflow.com/a/542339/1149664