コンストラクタから間接的に純粋仮想関数を呼べない

C++を使っていると、結構頭にクエスチョンがわくことが多い。おそらく、私がC++を深く理解出来ていないからだろうけど。

今回は、コンストラクタから間接的に純粋仮想関数を呼んだ場合の話。

#include <iostream>

class Base 
{
public:
	Base(){ caller(); }
	void caller() { call(); }
	virtual void call() = 0;
};

class Child : public Base
{
public:
	Child() : Base() {}
	void call() { std::cout << "hello" << std::endl; } 
};

int main(int argc, char** argv)
{
	Child child;
	child.caller();
}


親クラスのcallerメソッドから間接的に純粋仮想関数のcallを読んでいる。


この場合、コンパイルは上手くいく(直接、純粋仮想関数を呼ぶと、Warningがでますが、間接的な場合、Warningもでません)。
ただし、実行時にErrorになる。

% ./a.out
pure virtual method called
terminate called without an active exception
[2] 749 abort ./a.out


ここで、ふと不思議なことが。こういうのって普通にやる方法だよね?
と言うことで、コンストラクタではなく、明示的にcallerメソッドを呼び出した場合、

#include <iostream>

class Base 
{
public:
	Base() {}
	void caller() { call(); }
	virtual void call() = 0;
};

class Child : public Base
{
public:
	Child() : Base() {}
	void call() { std::cout << "hello" << std::endl; } 
};

int main(int argc, char** argv)
{
	Child child;
	child.caller();
}

実行すると、

% ./a.out
hello

と言うことで、想定通りの結果になる。


う〜ん、どうやらコンストラクタからは仮想関数を呼べないらしい。