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