ここは匣スマートフォン用の表示で見るここは匣この広告は、90日以上更新していないブログに表示しています。スマートポインタの話C++にはガーベジコレクタが言語的には存在しないので、動的に確保したオブジェクトのメモリの管理はプログラマが責任を持って管理しなければ、メモリリーク・リソースリークなどの問題を生じてしまいます。今時のプログラマはこうした問題を引き起こすリスクを減らす為に、記述ミスの起こりやすい生のポインタを使い自力でnewとdeleteを記述する事を避けて、安全なスマートポインタ、即ちオブジェクトの寿命により自動的にメモリ解放を行う便利なポインタを利用するべきです。スマートポインタと言っても種類が幾つかあり、落とし穴も存在するのでどういった状況でどれを利用するのが良いのかを考察してみます。C++11から随分増えていますねhttp://en.cppreference.com/w/cpp/memorystd::auto_ptrまずはauto_ptrです。このスマートポインタは、オワコンなので使ってはいけません。(deprecated)いかに、auto_ptrを駆使したテクニックがあるとしてもこれから使うべきではありません。このスマートポインタは幾つかの欠点を抱えている上、非推奨要素は規格からいずれ削除されてもおかしくないからです。説明の為にとりあげますが、このスマートポインタには先に述べた通り幾つかの問題があります。何年か前に書かれたコードで見かける事があるかもしれません。hoge);auto_ptrはスコープを外れると管理しているポインタを自動的にdeleteします。これにより、プログラマはdeleteを書き忘れメモリがリークする事を未然に防ぐ事が出来ます。auto_ptrには所有権が存在します。同じポインタに対して所有権を持つauto_ptrはたった1つでなければなりません。auto_ptr型の変数をコピーするとそのauto_ptrが管理しているポインタがコピー先に移動し、コピー元のauto_ptrはnullptrを指すようになります。コピーによって同一のオブジェクトを指すauto_ptrが増える事はなく、必ず1つのauto_ptrのみに保たれます。このようなコピーを破壊的なコピーと呼び、これがauto_ptrの所有権の決まりを成立させています。コピー以外の方法で所有権の決まりを無視して同一のオブジェクトを指す複数のauto_ptrを作成する事が可能で、その場合同じオブジェクトの削除が複数回行われ例外を発生させてしまいます。破壊的なコピーの問題から操作の中でコピーを用いる可能性があるコンテナに格納してはいけないといったデメリットがあります。他にも削除時の動作を指定出来ないなど、デメリットの詳細に関しては少し検索すれば沢山出てくるかと思います。これらのデメリットを克服したstd::unique_ptrスマートポインタが既にあるので、このスマートポインタは用いるべきではありません。std::unique_ptrauto_ptrの欠点を補ったスマートポインタです。コンテナに入れる事も出来、カスタムデリータを使用する事も出来ます。hoge_obj;auto_ptrの代わりにこちらを使うべきです。std::shared_ptrstd::shared_ptrは同様のObjectを指すshared_ptrが複数存在する事を許容するスマートポインタです。std::shared_ptrは現在幾つのshared_ptrが同じオブジェクトを指しているかのカウンタを持ちます。あるオブジェクトを指すshared_ptrが増えた時にカウンタを1つ加算し、減った時にカウンタを1つ減算します。最終的にどこからも参照されなくなったオブジェクトにアクセスする方法が存在しないので、カウンタが0になった際に自動的に対象オブジェクトをdeleteしてくれます。これによってメモリリークを防ぐ事が出来ます。非常に便利ですが、循環参照してしまった場合に解放されないという点に気をつけて下さい。スコープを抜けてもメモリは解放されずリークするこの問題の解決には後ほど記述するstd::weak_ptrを用います。loop);という方法でメモリを確保すべきではありません。これに関しても後ほど記述するstd::make_sharedで解説します。std::weak_ptrstd::weak_ptrは、既にshared_ptrにより管理されているオブジェクトへの弱参照を保持します。これはshared_ptrと違い、参照カウントに関わり無くスコープを抜けるとメモリを解放してくれます。これによって循環参照の問題を解決する事が出来ます。この問題を取り上げたこちらの記事が分かりやすいです。loop);という方法でメモリを確保すべきではありませんと書きました。その理由に関して説明します。);この関数は一般にT型のオブジェクトとそのshared_ptrの為のブロックの確保を1度のメモリ割り当て操作で行う事が期待されます。T(Args...))の記法を用いた宣言では少なくとも2度のメモリ割り当て操作が行われ、不要なオーバーヘッドを招くと考えられます。g())という記述はメモリリークを起こす可能性があります。これもmake_sharedを用いれば起こりません。std::make_shared<int>(10);といった風にstd::make_sharedを用いるべきなのです。allocで渡したアロケータを使えるmake_sharedと考えて良いと思います。自分もまだまだ理解が足りてないように思うので、C++のこわい方々は、この記事に間違いや補足などあればコメントで指摘してくださるとありがたいです。愚直に線形再帰して1つずつ処理していくとやはり再帰深度が問題...2013-10-09委譲コンストラクタで再帰する委譲コンストラクタで引数を増やしながら再帰してみました。en...2013-08-21TMPの条件分岐に条件演算子が使えても良い気がする以下のコードはgccでインスタンス化が無限再帰するコードです。pack長のindex_sequenceを構築する月別アーカイブはてなブログをはじめよう!fimbulさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。