脱線ついでに、、
> ポインタはバグの宝庫。なので、
こう片付けるのはどうかと。。
そもそもポインタがなんたるか、STLでどう管理しているかを
理解していれば、そもそもバグなんて出ないですし、
(1)のようなコードも書かないと思います。
クラスの構造から逆にポインタで管理した方がコードが
シンプルで見やすい・保守しやすいなんてこともあるかと。
ポインタはバグの巣であることは否定しないけども
かといって一掃することもできんのだから、
うまく折り合いをつけるが肝要かと。
バグを抑え込みつつ利用するひとつの手段がshared_ptrってーことで。
ポインタはバグの宝庫。
ポインタはバグの巣
という表現されてますが
ポインタという技術・考え方といったそのものに、
いかんともしがたいバグがあるのでしょうか?
そうすると、どういったバグなのでしょうか?
脱線が続くので、別スレッドを立てた方がよいのかも?
> 理解していれば、そもそもバグなんて出ないですし、
理解していても人間は間違えるものなので、バグは発生します。
> まずそもそも vector (に限らず STL コンテナ) にポインタ値を入れるという設計が
> あまりよくない (多態が必要な場合を除く) ので、その辺から再検討。
はtetrapodさんが理由をいってくれないと真意は分かりませんけどね。
私はSTLコンテナに(多態が必要な場合を除いて)ポインタ値を入れるのを「絶対」禁止
とは思っていませんが、バグが少なくなるならそれはその方がいいわけで、
επιστημηさんの
> かといって一掃することもできんのだから、
> うまく折り合いをつけるが肝要かと。
という意見に賛成です。
> そうすると、どういったバグなのでしょうか?
領域の解放忘れ(メモリリーク)
解放済みメモリへのポインタ(ダングリングポインタ)のアクセス
確保した領域を超えたアクセス
等々
しばらく見ないうちに盛り上がっている・・・呼んだ?
あくまでも俺個人の意見として maru 2009/10/28(水) 14:50:00 とほぼ同意。
代入可能やコピーコンストラクト可能でないクラスを STL コンテナに入れるのは困難
であり、STL コンテナに入るのはあくまでも元オブジェクトのコピー。
コピー=新しい実体である、ということ。
RAII 的観点からも STL コンテナには実体が入っているほうが扱いやすいよね。
コンテナの消滅=管理しているオブジェクトの実体の消滅になるわけで。
生ポインタ値をコンテナに入れたら、ポインタ値のコピーが作られるだけなので
ポインタが指す先の実体のコピーはなされない。
コンテナ(とそれに入っているポインタ値)があっても、それが指し示すべき実体が
ないという状況が安易に作れてしまいバグの元だ。と思う。
コンテナを消滅させても実体が残りうるのはバグの元だと思う。
生ポインタ値を入れるのは推奨しないとは書いたが shared_ptr<T> を入れることまで
ダメとは書いた覚えがない。設計上、コンテナにポインタを入れる必然があるなら
諸氏と同様、俺も shared_ptr<T> を使うのを推奨する。
rin 氏
およそコンピュータというものは間違わないわけよ。
「プログラムに書かれたとおりに動作する」という点で。
間違うのは人間。
ポインタそのものにバグはなく、ポインタを使う人間のほうが誤りやすいだけ。
ならば人間の誤りを可能な限り減らすように最初から心がけるほうがいい。
vector<T*> より vector<T> のほうがバグらせにくい、
vector<T*> より vector<shared_ptr<T> > のほうがバグらせにくい、
んではないかな、と俺は思う。
> しばらく見ないうちに盛り上がっている・・・呼んだ?
はい。
tetrapodさんの
> rin 氏
> およそコンピュータというものは間違わないわけよ。
> 「プログラムに書かれたとおりに動作する」という点で。
> 間違うのは人間。
> ポインタそのものにバグはなく、ポインタを使う人間のほうが誤りやすいだけ。
をみて、自分がrinさんの質問を読み違えていたことに気付きました。
「ポインタという技術・考え方といったそのもの」にバグがあるわけではないんですよ
ね。
なので、
> 領域の解放忘れ(メモリリーク)
> 解放済みメモリへのポインタ(ダングリングポインタ)のアクセス
> 確保した領域を超えたアクセス
> 等々
は質問の回答になっていません。撤回します。
その例はある意味 rin 氏の質問に対する回答の一例ではあるわけだけど
ポインタという技術なり考え方なりはきわめて「機械にとって単純」なものなので、
それ自体がバグなり不具合なりを抱え込んでいるわけではない。
「機械にとって簡単」≠「人間にとって簡単」ということ。
> 領域の解放忘れ(メモリリーク)
> 解放済みメモリへのポインタ(ダングリングポインタ)のアクセス
> 確保した領域を超えたアクセス
というのは人間側の間違いかたの例ということで。