呼ばれるタイミング

C++の、コンストラクタとかデストラクタとかコピーコンストラクタとかの呼ばれるタイミングとかがイマイチ感覚としてわからん。以下のようなコードを実行してみたりして、まあ自分で定義したものはだいたいこんな感じかなー、と想像することはできるかなあ。あんまわからん。

#include <iostream>
using namespace std;
class Fuga {
  public:
    string name;
    Fuga(string _name)
    {
      name = _name;
      cout << "new " << name << endl;
    }
    ~Fuga()
    {
      cout << "delete " << name << endl;
    }
    Fuga(Fuga& ref)
    {
      name = "Copy" + ref.name;
      cout << "copy " << name << endl;
    }
};
class Hoge {
  public:
    Fuga *child;
    string name;
    Hoge(string _name)
    {
      name = _name;
      child = new Fuga("Child"+name);
      cout << "new " << name << endl;
    }
    ~Hoge()
    {
      delete child;
      cout << "delete " << name << endl;
    }
    Hoge(Hoge& ref)
    {
      name = "Copy" + ref.name;
      child = new Fuga("Child"+name);
      cout << "copy " << name << endl;
    }
};
Hoge& hogef(Hoge hoge)
{
  puts("in hogef");
  return hoge;
}
int main(int argc, char *argv[])
{
  puts("m1");
  Hoge hoge("HOGE");
  puts("m2");
  Hoge fuga = hogef(hoge);
  puts("m3");
  return 0;
}

実行するとこんなんで、引数と返り値の受け渡しは値渡しで基本コピーコンストラクタ経由になると。で、スコープの外になって消すときにはデストラクタを呼んでくれる。

% ./a.exe 
m1
new ChildHOGE
new HOGE
m2
new ChildCopyHOGE
copy CopyHOGE
in hogef
new ChildCopyCopyHOGE
copy CopyCopyHOGE
delete ChildCopyHOGE
delete CopyHOGE
m3
delete ChildCopyCopyHOGE
delete CopyCopyHOGE
delete ChildHOGE
delete HOGE

まあそういうのはさておいて、stringのname = _name;とかがわからんなー。あー、basic_stringがその定義か。templateだな。


「better CとしてC++を使う」にしても、templateわからんとやっぱりスッキリ気持ち良く使えねえなー。なんかこういいかげんに手探りするよりやっぱりすっぽすぽ先生の原典読もう。わりとおもしろそうだったし。

test