読者です 読者をやめる 読者になる 読者になる

どこに向けてでもなく仮想関数とかなんとか

Java(とか仮想関数がふつー)な人がC++書いたときにはまりそうな予感がしたので書いてみる。

C++のクラス、

class CHoge {
public:
	void hoge( ) {
		printf("hoge\n" );
	}
};

class CHogehoge : public CHoge {
public:
	void hoge( ) {
		printf("hogehoge\n" );	
	}
};

int main(int argc, char *argv[])
{
	CHogehoge* hogehoge = new CHogehoge();
	CHoge* hoge = hogehoge;
	hoge->hoge();
        delete hoge;
}

と書いたとき、Javaの人が期待する出力は、
hogehogeだと思う。
だって、
hogehogeは、CHogehogeのインスタンスとしてnewされていて、
hogeに代入されようとCHogehogeであることは変わらないから、CHogehogeとしての振る舞いを期待する筈だ。

だが、これは見事に期待を裏切って無情にも
hoge
を出力する。
これは、C++のメソッドの振る舞いがデフォルトでvirtualでないためだ。
もう全部virtualでいいじゃん、としたのはやっぱりわかりやすいからだろうなぁ、とか思う。
(インライン展開とかさておく)
なじみのないデストラクタでもこれが起こるので発狂するのではないか。
(CHogeのポインタをdeleteしてもデストラクタがvirtualでない限りCHogehogeのデストラクタは呼ばれない=リソースリークよこんにちは)