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の良さを手に入れます。