Основное отличие — в количестве выделений памяти:
shared_ptr: Требует двух отдельных выделений памяти. Одно для самого объекта, другое для управляющего блока (control block), содержащего счетчики ссылок и прочую метаинформацию.make_shared: Выполняет одно единое выделение памяти для объекта и управляющего блока совместно.| Характеристика | Конструктор shared_ptr | make_shared |
|---|---|---|
| Количество аллокаций | Две | Одна |
| Эффективность | Менее эффективен | Более эффективен |
| Гарантии исключений | Меньше (возможна утечка в выражении) | Больше (атомарная операция) |
| Использование динамического массива | Возможен (std::shared_ptr<T[]>) | Невозможен (std::make_shared<T[]>) |
Пример с конструктором:
c
Пример с make_shared:
c
Использование make_shared предпочтительнее в большинстве случаев из-за лучшей производительности и безопасности исключений. Однако, существуют сценарии, где только конструктор подходит, например, при создании shared_ptr из уже существующего "голого" указателя или при работе с пользовательскими аллокаторами.