static 変数の呪い

恥ずかしながら、メンバー関数内で定義した static 変数「も」インスタンス間で共有されるということを知りませんでした。

#include <iostream>
class base {
    void func_private() {
	static int i = 0;
	std::cerr << "private=" << i ++ << ", ";
    }
protected:
    static int i_;
    void func_protected() {
	static int i = 0;
	func_private();
	std::cerr << "protected=" << i ++ << ", ";
    }
public:
    virtual void func_public() {
	static int i = 0;
	func_protected();
	std::cerr << "base    public=" << i ++ << ", class=" << i_ ++ << std::endl;
    }
};

int base::i_ = 0;

class derived: public base {
public:
    virtual void func_public() {
	static int i = 0;
	func_protected();
	std::cerr << "derived public=" << i ++ << ", class=" << i_ ++ << std::endl;
    }
};

int main(int argc, char** argv) {
    base base1, base2;
    derived derived1, derived2;

    base1.func_public();
    base2.func_public();
    derived1.func_public();
    derived2.func_public();

    base1.func_public();
    base2.func_public();
    derived1.func_public();
    derived2.func_public();
}

実行してみます。

private=0, protected=0, base    public=0, class=0
private=1, protected=1, base    public=1, class=1
private=2, protected=2, derived public=0, class=2
private=3, protected=3, derived public=1, class=3
private=4, protected=4, base    public=2, class=4
private=5, protected=5, base    public=3, class=5
private=6, protected=6, derived public=2, class=6
private=7, protected=7, derived public=3, class=7

わーお!