ゆとりーなの日記

日記的な事を書いて行くと思はれる

訂正:自機と言えばやっぱり四式戦闘機「疾風」

昨日は東方の香り漂う記事になってしまいました。なんでそうなったかを弁解しておくと、一昨日の記事のタイトルが東方の香りしかしないものだったのに、全く東方について触れていませんでした。昨日とあるきっかけではてなキーワードの「アリス(本名の長ったらしい方)」を見る機会があったんですが、当然含むブログのとこに載ってますよね。全然関係ない記事なのに。周辺のブログを見るとちゃんと東方について書いてるんですよね。というわけで反省して昨日は東方ネタでいきました。というか記事名もっと考えた方がいいですね。自分で書いた記事見なおすときもタイトルが意味不明で目的の記事が探すのが地味に大変だったりします。変数の命名法考えるよりも先ずは記事名ですかね。今日の記事名では早速活かされていませんが。

関数内のstatic変数

今日は特集ではありません。特集って銘打つほどの内容じゃありませんので。今日は関数内static変数についての思い出です。

関数内のstatic変数は便利だな〜

関数内のstatic変数を使うと次のようなことが出来ます。

#include <iostream>

void numberPrint() {
  static int i;
  std::cout << i << std::endl;
  ++i;
}

int main() {
  numberPrint();
  numberPrint();
  return 0;
}

結果出力:
0
1

関数内の変数は、通常であればリセットされますが、staticを付けとくとまさかの保存されるんですね。呼び出し毎に値を1増やすなんてことも余裕で出来ます。これはRPGC/C++」の序盤のダンジョン攻略の頃は便利だな〜と思うことが多いのではないでしょうか。私はそう思ってました。ところが物語も進み、パーティを分割して攻略するダンジョンに差し掛かると、一気に関数内のstatic変数を避けるようになります。危険が大きいんですね。まあ今回はこれは主題ではないのでこのへんで。

メンバ変数内のstatic変数は便利だな〜?

クラスを覚えるとメンバ関数内にもstatic変数を使ってみたくなります。で、使ってみます。

#include <iostream>

class A {
public:
  A() {}
  void numberPrint() {
    static int i;
    std::cout << i << std::endl;
    ++i;
  }
};

int main() {
  A a, b;
  a.numberPrint();
  b.numberPrint();
  a.numberPrint();
  return 0;
}

当時の私の結果出力への期待:
0
0
1

裏切られた結果出力:
0
1
2

当初私は上の方の出力になるものだと思ってました。インスタンス毎に別の関数を呼んでる感があったので、static変数も別々だと思ったんですね。

// 当初の私の脳内
void instans_a_numberPrint() {
  static int i;
  std::cout << i << std::endl;
  ++i;
}

void instans_b_numberPrint() {
  static int i;
  std::cout << i << std::endl;
  ++i;
}

int main() {
  instans_a_numberPrint();
  instans_b_numberPrint();
  instans_a_numberPrint();
  return 0;
}

今にして思うとこれじゃあテンプレートですね。正解は多分こんな感じです。

void instans_numberPrint(A *p) {
  static int i;
  std::cout << i << std::endl;
  ++i;
}

int main() {
  A a, b;
  instans_numberPrint(&a);
  instans_numberPrint(&b);
  instans_numberPrint(&a);
  return 0;
}

こう考えると結果出力も頷けますね。