make_shared (<memory>)
既定のアロケーターを使用してゼロ以上の引数から構築された割り当て済みオブジェクトを指し示す shared_ptr を作成し、返します。 指定された型のオブジェクトおよび shared_ptr の両方を割り当て構築することでオブジェクトの共有所有権を管理し、shared_ptr を返します。.
template<class Type, class... Types> shared_ptr<Type> make_shared( Types&&... _Args );
パラメーター
パラメーター |
説明 |
---|---|
_Args |
0 個以上のコンス トラクター引数。 関数は、提供された引数に基づいてどのコンストラクターのオーバーロードを呼び出すかを推測します。 |
プロパティ値/戻り値
割り当てられ構築されたオブジェクトを指し示す shared_ptr を返します。
解説
オブジェクトを作成するための簡単で効率的な方法として make_shared を使用し、同時にオブジェクトへの共有アクセスを管理するために shared_ptr を使用します。 意味的には、これら 2 つのステートメントは同等です。
auto sp = std::shared_ptr<Example>(new Example(argument));
auto msp = std::make_shared<Example>(argument);
しかし、最初のステートメントで 2 つの割り当てが実行され、Example オブジェクトが正常に完了した後、shared_ptr の割り当てが失敗すると、名前のない Example オブジェクトがリークされます。 make_shared を使用するステートメントの方が、関数呼び出しが 1 つしか関係しないので簡単です。 ライブラリがオブジェクトとスマート ポインターの両方に対して単一の割り当てを行うことができるため効率的です。 こちらの方が高速でメモリの断片化が少なくなります、1 つは割り当てられてもう 1 つは割り当てられないという例外が発生する可能性はありません。 スマート ポインターでオブジェクトを参照したり参照カウントを更新したりするコードでは、局所性の改善によってパフォーマンスが向上します。
オブジェクトへの共有アクセスを必要としない場合、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();
}
この例では、次の出力が生成されます:
必要条件
ヘッダー: <memory>
名前空間: std