ポインタの使用

この記事は,C++プログラマであるかを見分ける10の質問 - Life like a clown の「ポインタの使用方法について,メモリーリーク問題等と絡めながら戦略を述べよ」に対する回答的な記事です.

ポインタの使用に関する戦略ですが,経験上は以下の 2点辺りになるかと思います.

  • C++ は意外とポインタ(と言うよりは動的なメモリ確保)をユーザが明示的に使わずとも何とかなるケースが多いです.STL コンテナ等すでに用意されてあるライブラリの使用も考慮に入れ,本当にポインタが必要な場面かどうかを熟考しましょう.
  • ポインタが必要になった場合,「自力で後処理をする」と言う思想は危険なのでスマートポインタを使用するようにしましょう.

あんまりメモリリークの話絡めてないですね.

スマートポインタに関しては ポインタは用法用量を守って正しくお使いください - kikairoyaの日記 で上手く纏められていますので詳細はそちらを参照下さい.スマートポインタに関しては,現状では shared_ptr を使うと言う選択肢が一番多いだろうと予想されますので,「どの shared_ptr を使うか」と言う事について少し検討してみます.

まず,Boost C++ Libraries が使える(使う事を許されている)環境では boost::shared_ptr を使うのがベストでしょう.何らかの理由で Boost の使用が許されていない環境の場合は,コンパイラが比較的新しければ std::tr1::shared_ptr が存在するかと思いますのでそれを使用します.std::tr1::shared_ptr も存在しない場合は・・・自作になるでしょうか.ただし,shared_ptr および shared_array の実装は(その必要性から)多くの人が実装していますので,自分で作ると言う道を選ぶよりは既に誰かが実装した shared_ptr を持ってくる方が良いと思います.

現在の C++ に標準ライブラリとして唯一存在するスマートポインタである auto_ptr は扱いが難しいです.個人的な経験では,狭いスコープ内で new して一時変数に格納する(すぐに開放する)ようなケースでは auto_ptr でも良いかなと言う感じです.

纏めると以下のような形になります.

  1. Boost C++ Libraries が使えるなら boost::shared_ptr を使用する.
  2. TR1 が実装されている環境であれば std::tr1::shared_ptr を使用する.
  3. サードパーティ製の shared_ptr.h などを探して利用する.
  4. std::auto_ptr で代替する(限定的).

C++ でポインタが使われるケースは「コピーで発生するコストを嫌って」と言う話もしばしば耳にしますが,C++0x でムーブが定着するにつれてこの問題も少しずつ解消していく事が予想されます.その意味でも,そのコスト回避はどうしても必要なのかどうかはよく検討し,局所的な最適化はできるだけ抑えて,メモリ管理は標準ライブラリなどに任せるスタイルに移行しておく方が良いかなと個人的には思っています.