[解決済み] shared_ptr to an array : 使うべきですか?
質問
に関するちょっとした質問です。
shared_ptr
.
を使用するのは良い習慣ですか?
shared_ptr
は配列を指しているのですか? 例えば
shared_ptr<int> sp(new int[10]);
そうでないとしたら、なぜそうしないのか?私がすでに知っている理由のひとつは、このメソッドでは
shared_ptr
. したがって、配列への通常のポインタのようには使用できません。
どのように解決するのですか?
と
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
. もし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[]
C++ Extensions for Library Fundamentalsによって導入された変更点
上に挙げたものに代わるものとして、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*
.
関連
-
[解決済み】Enterキーを押して続行する
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] std::move()とは何ですか?また、どのような場合に使用するのですか?
-
[解決済み] C++のmake_sharedと通常のshared_ptrの違いについて
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】なぜC++プログラマは'new'の使用を最小限に抑えなければならないのでしょうか?
-
[解決済み】shared_ptrは参照で渡すべきか、値で渡すべきか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較