コンストラクタから間接的に純粋仮想関数を呼べない
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
と言うことで、想定通りの結果になる。
う〜ん、どうやらコンストラクタからは仮想関数を呼べないらしい。