pure virtual function

いわゆる純粋仮想関数。
持ってるクラスは抽象クラスになる。

微妙に抽象クラスとインターフェースの違いが分かってないけど、変数持ってるかどうかだけで決まるんだよね?
まぁC++だとabstractとかinterfaceとか言う概念からしてないからあんまり気にしなくていいのかもだけど。


それはさておき

#include <iostream>

class MHoge{
	public:
	MHoge(void){};
	virtual ~MHoge(void){};

	virtual void doSomething(void) = 0;	//pure virtual
	
};

class CHoge : public MHoge{
	public:
		CHoge(void) : MHoge() {};
		~CHoge(void){};
		
		void doSomething(int get=0){ // implement! (compile error)
			std::cout << "get number: " << get << std::endl;
		};
};

int main(void){
	CHoge hoge;
	hoge.doSomething();
	return 0;
}

これをコンパイルするとdoSometing(void)がオーバーライドされていないということで怒られた。
のやさん的には見逃してくれると信じていたので結構ビックリ。
だからといって

class CHoge : public MHoge{
	public:
		CHoge(void) : MHoge() {};
		~CHoge(void){};
		
		void doSomething(void){
			std::cout << "hogehoge!" << std::endl; 
		};
		void doSomething(int get=0){
			std::cout << "get number: " << get << std::endl;
		};
};

こーするとCHoge::doSomething()を呼び出したときにどっちを呼び出していいかわからなくなって困るらしい。そりゃそーだ

んで、この問題が真に怖いのは

int main(void){
	CHoge hoge;
	//hoge.doSomething();
	hoge.doSomething(10);
	return 0;
}

なんてやるとさっくりコンパイルが通ってしまうこと。
# Wallオプションでもワーニングすらでない!

つまり曖昧なdoSomething()は曖昧な呼び出され方をしない限りは見逃してくれる。
きっと考えてる振る舞いと異なるのでこーいうことはやめておこうっと。
どうしてもやりたければ

class CHoge : public MHoge{
	public:
		CHoge(void) : MHoge() {};
		~CHoge(void){};
		
		void doSomething(void){
			doSomething(0);
		};
		void doSomething(int get){
			std::cout << "get number: " << get << std::endl;
		};
};

多分これが一番やりたい挙動。

だけどのやさん的にはやっぱり最初のソースで見逃して欲しいなー