
読書記録
読者プロフィール
組み込みエンジニア。お仕事はC言語をメインで使う。オブジェクト指向言語でのプロダクト開発経験あり。
雑感
率直にいってとても困惑している。
2017年に本書の第二版を読んでおり、当時良い印象を持った記憶があった。第三版が出てるとのことで読んでみたのだが、引っかかるポイントがあったり、全体的に薄い内容に感じてしまった。読む前は楽しみにしていたはずなのになぜだろうか…。期待値が高かった分ギャップが大きくなってしまったのかもしれない。
・全体的に内容が浅く新しい知識を得られなかった。(目次は第二版からほぼ変化無し)
タイトルに基礎知識ってあるからこんなもんなのかもしれない。
・「オブジェクト思考でなぜ作るか」という問いに対する回答が無いように思える。タイトルは「オブジェクト指向とは」の方が実態に近い気がする。
・(時代的な背景の差として理解できるが)オブジェクト指向の比喩やコンセプトの分かりにくさを繰り返し説明されるが、そもそも遭遇したことがないのでピンとこない。
第三版を読む前はおススメできる本だと思っていたはずだけど、おすすめしないかな。オブジェクト指向について全く分かっていないなら読むのはあり。その場合は古い版を中古で買えばOK。
あらすじ
本書はJavaで解説されているが詳細な言語仕様については触れていない。メモリの説明で少し検証したのでそこだけ書いておく。
メモリの使い方
インスタンス生成時はヒープ領域が使われるとある。Javaではそうなのかもしれないが、newを使うからでは?と思いc++で簡単に確認した。汎用PCでスタックやヒープの領域を確認する方法が分からなかったので、実験的にグローバル領域、ヒープ、スタックのアドレスを求め分類した。
静的メンバはクラス定義とともにロードされるはずなので、そのアドレスを出力することでクラスのロード状況を間接的に見てみる。
int Person::staticMember = 0;
int va11=0;
int main(){
int val2;
int* val3=(int*)malloc(10);
int* val4 = new int[10];
Person personNotNew("Taro", 25);
Person* personNew = new Person("Taro", 25);
printf("GlobalVal %p\n",&va11);
printf("LocalVal %p\n",&val2);
printf("MallocInt %p\n",val3);
printf("NewInt %p\n",val4);
printf("StackClass %p\n",(void*)&personNotNew);
printf("NewClass %p\n",(void*)personNew);
printf("StaticClass %p\n",(void*)&Person::staticMember);
GlobalVal 00007FF7329690A4
LocalVal 0000002A50FFFDCC
MallocInt 0000013A767A1C90
NewInt 0000013A76751260
StackClass 0000002A50FFFDA0
NewClass 0000013A767515D0
StaticClass 00007FF7329690A0
つまり以下のようになる。私の理解とも一致するので違和感はない。クラスインスタンスはnewすればヒープに作成され、ローカル変数として定義すればスタックに定義される。
グローバル | ヒープ | スタック | |
---|---|---|---|
グローバル変数 | 〇 | ||
class定義 | 〇 | ||
ローカル変数、ローカルインスタンス | 〇 | ||
malloc,new | 〇 |
本書ではJavaを用いている。Javaでは動的メモリの回収はガベージコレクションによっておこなれるため通常インスタンスはヒープに生成される。
ガベージコレクションの無い言語(C++)ではヒープにインスタンスを置くメリットは薄まる。通常の変数と同様にスタック管理とするかヒープ管理とするかは選択できる。なおc++ではスマートポインタがあるため通常メモリの破棄は不要。Rustは勉強中だが、こちらもGCは無いがメモリリーク防止を言語がサポートしている。