C ++ 17、shared_ptr動的に割り当てられたアレイを管理するために使用することができます。shared_ptrこの場合のテンプレート引数は、T[N]またはでなければなりませんT[]。だからあなたは書くかもしれません
shared_ptr<int[]> sp(new int[10]);
n4659以降、[util.smartptr.shared.const]
template<class Y> explicit shared_ptr(Y* p);
必要: Y完全なタイプでなければならない。式はdelete[] p、時にT配列型である、またはdelete pとき、T配列型ではなく、行動を明確に定義されなければならない、と例外をスローしてはなりません。
...
備考:ときTアレイ型で発現がない限り、このコンストラクタは、オーバーロード解決に参加してはならないdelete[] pだけでなく、形成されており、いずれかTであるU[N]とY(*)[N]に変換されT*、またはTであり
U[]且つY(*)[]に変換可能T*。...
これをサポートするために、メンバータイプelement_typeは次のように定義されています。
using element_type = remove_extent_t<T>;
配列要素には、 operator[]
element_type& operator[](ptrdiff_t i) const;
必要です: get() != 0 && i >= 0。IFがTありますU[N]、i < N。...
備考:Tが配列型でない場合、このメンバー関数が宣言されているかどうかは不定です。宣言されている場合、関数の宣言が(必ずしも定義であるとは限りませんが)整形式であることを除いて、戻り型が何であるかは不明です。
C ++ 17の前に、shared_ptr可能性がない動的に割り当てられたアレイを管理するために使用すること。デフォルトでshared_ptrはdelete、管理オブジェクトへの参照がなくなると、は管理オブジェクトを呼び出します。ただし、を使用して割り当てる場合は、ではなくnew[]を呼び出してdelete[]、deleteリソースを解放する必要があります。
shared_ptr配列で正しく使用するには、カスタムの削除機能を提供する必要があります。
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
次のようにして、shared_ptrを作成します。
std::shared_ptr<int> sp(new int[10], array_deleter<int>());
今shared_ptr正しく呼び出すdelete[]管理対象オブジェクトを破壊したとき。
上記のカスタム削除ツールは、
std::default_delete配列型のための部分的な特殊
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
ラムダ式
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
また、管理対象オブジェクトの共有管理を実際に必要としない限りunique_ptr、配列型を部分的に特殊化しているため、このタスクにはが適しています。
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]
Library FundamentalsのC ++拡張機能によって導入された変更
上記にリストされたものの別のC ++ 17以前の代替は、ライブラリの基本技術仕様によって提供されましたshared_ptr。これは、オブジェクトの配列を所有する場合にそのまま使用できるように拡張されました。shared_ptrこのTSに予定されている変更の現在のドラフトは、N4082にあります。これらの変更はstd::experimental名前空間を介してアクセスでき、<experimental/memory>ヘッダーに含まれます。shared_ptrアレイのサポートに関連するいくつかの変更は次のとおりです。
—メンバータイプの定義がelement_type変更された
typedef T element_type;
typedef typename remove_extent<T>::type element_type;
—メンバーoperator[]が追加されています
element_type& operator[](ptrdiff_t i) const noexcept;
-とは異なりunique_ptr、両方、配列のための部分的な特殊化shared_ptr<T[]>とshared_ptr<T[N]>有効になり、両方ともにつながるdelete[]オブジェクトの管理配列に呼び出されています。
template<class Y> explicit shared_ptr(Y* p);
必要:Y完全なタイプである必要があります。表現delete[] p、T配列型である、またはdelete pとき、T配列型ではありませんが、整形式でなければならない、明確に定義された振る舞いを持たなければならない、と例外をスローしてはなりません。ときTであるU[N]、Y(*)[N]に変換しなければなりませんT*。ときTであるU[]、Y(*)[]に変換しなければなりませんT*。それ以外の場合は、Y*に変換できT*ます。
std::vector。コピーを作成しないように、参照を使用して配列を渡すように注意する必要があります。データにアクセスするための構文は、shared_ptrよりもきれいで、サイズ変更は非常に簡単です。そして、あなたが望むなら、あなたはすべてのSTLの良さを手に入れます。