Почему рекомендуют использовать std::make_shared
1️⃣ Как кратко ответить
Использование std::make_shared рекомендуется, потому что оно более эффективно и безопасно, чем прямое использование конструктора std::shared_ptr. Оно выполняет единую аллокацию памяти для объекта и управляющего блока, что уменьшает накладные расходы и снижает вероятность ошибок, связанных с управлением памятью.
2️⃣ Подробное объяснение темы
std::make_shared — это функция, которая создает объект и возвращает std::shared_ptr, указывающий на этот объект. Она была введена в C++11 и является предпочтительным способом создания объектов, управляемых std::shared_ptr, по нескольким причинам.
Эффективность
Когда вы используете std::make_shared, память для самого объекта и управляющего блока (который хранит счетчик ссылок и другую служебную информацию) выделяется за один вызов аллокатора. Это уменьшает количество операций выделения памяти, что может значительно повысить производительность, особенно в системах с ограниченными ресурсами.
Пример:
#include <memory>
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "MyClass constructor\n";
}
~MyClass() {
std::cout << "MyClass destructor\n";
}
};
int main() {
// Создание объекта с использованием std::make_shared
std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();
return 0;
}
std::make_shared<MyClass>()создает объектMyClassиstd::shared_ptr, указывающий на него, за одну операцию выделения памяти.
Безопасность
Использование std::make_shared снижает вероятность ошибок, связанных с управлением памятью. Например, если вы создаете объект с помощью new и затем передаете его в конструктор std::shared_ptr, существует риск утечки памяти, если произойдет исключение между этими двумя операциями.
Пример потенциальной проблемы:
#include <memory>
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "MyClass constructor\n";
}
~MyClass() {
std::cout << "MyClass destructor\n";
}
};
int main() {
// Потенциально небезопасный способ создания shared_ptr
MyClass* rawPtr = new MyClass();
std::shared_ptr<MyClass> ptr(rawPtr);
return 0;
}
- Если между
new MyClass()иstd::shared_ptr<MyClass> ptr(rawPtr)произойдет исключение, объектMyClassне будет освобожден, что приведет к утечке памяти.
Применение
std::make_shared широко используется в современных C++ приложениях, где требуется управление временем жизни объектов. Это особенно полезно в многопоточных приложениях, где важно минимизировать накладные расходы на управление памятью и избегать ошибок, связанных с конкурентным доступом к ресурсам.
Заключение
Использование std::make_shared — это не только вопрос стиля, но и практическая необходимость для написания более эффективного и безопасного кода. Оно упрощает управление памятью и снижает вероятность ошибок, что делает его предпочтительным выбором для создания объектов, управляемых std::shared_ptr.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться