まぁなんでプログラミング10何年もやってて知らないんだって話しです。

冷静に考えると特に必要はなかった気もするんですが、実験のデータ加工をするプログラムをC++で書いてみました。
C++あまり使ったことなかったのですが、最近のプログラミング言語に比べて割と挙動が違うのでコツが必要だった。

ようは一番何が違うかというと、オブジェクトとそれを格納する変数の取り扱いが違う。

C++:
  1. MyClass mc;

と書くと、たとえばjavaとかの場合mcにはnullが入っているわけですが、c++の場合暗黙にコンストラクタMyClass()が呼び出されて初期化されます。
どういう差かというとjavaの場合オブジェクト型を入れる変数は全部ポインタなんですね。だから宣言しただけだとnull(pointer)が入ってるわけです。
C++の場合普通に宣言すると、ちょうどCの構造体と同じ扱いになります。つまり基本的には「値」扱いみたいな感じになります。
なのでC++にはガーベッジコレクトがないわけですが、上のように宣言すると(mcの内部の話は別として)mc自体は破棄されます。

これを確認するのに一時間くらいテストコード書いてた・・・・

つまりは、C++で

C++:
  1. MyClass * mc = new MyClass();

と書く場合がjavaのデフォルトで、ただし、ガーベッジコレクトがあるおかげで、なんか適当な感じにできてるわけです。
この辺はrubyとか、たぶんpythonも一緒。

で、問題はガーベッジコレクトがないところで、newなどで動的にメモリ確保をした場合が割りとめんどくさいのです。

たとえばつぎのようなクラスを作ったとします。このクラスはあまり設計的によろしくないような感じがします。

C++:
  1. class MyClass{
  2. public:
  3. Foo* hogefunc();
  4. }
  5.  
  6. Foo* hogefunc()
  7. {
  8. return new Foo();
  9.  
  10. }

こういう風にした場合hogefunc()で作られたFooのメモリが開放されません。どっかでdeleteしないといけないんでしょうが、どこでやったものかという悩みが発生します。
ちなみにjavaとかだとまったく問題ないんだけども。

MyClassのデストラクタでやるとするとMyClassが破棄された時点でFooが消えるので、メモリの変なところへアクセスしたりしそうです。
一方で、(この場合は問題にならないですが)MyClassの外で消すと、MyClass内の処理で引っかかりそうです。

なんか適当に作ってしまったので、いまさら変更するのもなーと思って放置なんですが、どうやるのが美しいのかなぁ。
new使わずにやるのがよさそうかな。

けどその場合の帰り値はコピーコンストラクタとかが使われることになるのかな。解決できる問題ではあるんだけど、めんどくさいのとC++の流儀がどうなってるのかがひっかかってるはらじゅんでした。