Поделиться через


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

См. также

Ссылки

<memory>

Класс shared_ptr