make_shared (<memory>)
Создает и возвращает shared_ptr, указывающий на выделенные объекты, созданные без аргументов или с помощью нескольких аргументов с использованием распределителя по умолчанию. Выделяет и создает объект указанного типа и shared_ptr для управления общим владением объекта и возвращает shared_ptr.
template<class Type, class... Types> shared_ptr<Type> make_shared( Types&&... _Args );
Параметры
Параметр |
Описание |
---|---|
_Args |
Без аргументов или несколько аргументов конструктора. Функция определяет перегрузку конструктора, которую нужно вызвать, на основе переданных аргументов. |
Значение свойства, возвращаемое значение
Возвращает объект shared_ptr, указывающий на выделенный и созданный объект.
Заметки
Используйте одновременно make_shared как простой и эффективный способ создания объекта и shared_ptr для управления общим доступом к объекту. Семантически следующие два оператора эквивалентны:
auto sp = std::shared_ptr<Example>(new Example(argument));
auto msp = std::make_shared<Example>(argument);
Однако первый оператор назначает два выделения, и при сбое выделения shared_ptr после успешного выделения объекта Example происходит утечка неименованного объекта Example. Оператор с make_shared проще, поскольку используется только один вызов функции. Он более эффективен, так как библиотека может создать одно и то же выделение для объекта и интеллектуального указателя. Это более быстрый способ, и меньше фрагментируется память, и, кроме того, становится невозможным возникновение исключения только в одном выделении из двух. Благодаря более оптимальному расположению кода, указывающего на объект и обновляющего счетчики в интеллектуальном указателе, повышается производительность.
Если общий доступ к объекту не требуется, рассмотрите возможность использования make_unique. Если необходимо указать пользовательский распределитель для объекта, используйте allocate_shared. Вы не можете использовать make_shared, если объект требует пользовательский метод удаления, так как метод удаления невозможно передать в качестве аргумента.
В приведенном ниже примере показано, как можно создавать общие указатели на тип, задавая определенные перегрузки конструктора.
Пример
// stl_make_shared.cpp
// Compile by using: cl /W4 /EHsc stl_make_shared.cpp
#include <iostream>
#include <string>
#include <memory>
#include <vector>
class Song {
public:
std::wstring title_;
std::wstring artist_;
Song(std::wstring title, std::wstring artist) : title_(title), artist_(artist) {}
Song(std::wstring title) : title_(title), artist_(L"Unknown") {}
};
void CreateSharedPointers() {
// Okay, but less efficient to have separate allocations for
// Song object and shared_ptr control block.
auto song = new Song(L"Ode to Joy", L"Beethoven");
std::shared_ptr<Song> sp0(song);
// Use make_shared function when possible. Memory for control block
// and Song object are allocated in the same call:
auto sp1 = std::make_shared<Song>(L"Yesterday", L"The Beatles");
auto sp2 = std::make_shared<Song>(L"Blackbird", L"The Beatles");
// make_shared infers which constructor to use based on the arguments.
auto sp3 = std::make_shared<Song>(L"Greensleeves");
// The playlist vector makes copies of the shared_ptr pointers.
std::vector<std::shared_ptr<Song>> playlist;
playlist.push_back(sp0);
playlist.push_back(sp1);
playlist.push_back(sp2);
playlist.push_back(sp3);
playlist.push_back(sp1);
playlist.push_back(sp2);
for (auto&& sp : playlist) {
std::wcout << L"Playing " << sp->title_ <<
L" by " << sp->artist_ << L", use count: " <<
sp.use_count() << std::endl;
}
}
int main() {
CreateSharedPointers();
}
В примере получается следующий результат.
Требования
Заголовок: <память>
Пространство имен: std