今更言う事でもないが、コンストラクタで仮想メソッドを呼んでも意図通りに動かない。
C++
class BaseClass
{
public:
BaseClass()
{
cout << "BaseClass ctor\n";
Func();
}
virtual void Func()
{
cout << "BaseClass Func()\n";
}
};
class InheritClass : public BaseClass
{
public:
InheritClass()
{
cout << "InheritClass ctor\n";
}
void Func()
{
cout << "InheritClass Func()\n";
}
};
int main()
{
BaseClass* p = new InheritClass();
p->Func();
return 0;
}
実行結果
BaseClass ctor
BaseClass Func()
InheritClass ctor
InheritClass Func()
何故このような結果になるのだろうか。2 行目は「InheritClass Func()」ではないのか?
BaseClass* p = new InheritClass();
InheritClass のコンストラクタを呼び出そうとし、基底クラスがあるので、その前に BaseClass のコンストラクタを呼ぶ。それから InheritClass のコンストラクタを呼ぶ。要するに、BaseClass() → InheritClass() の順で呼び出されている。
コンストラクタの呼び出しが完了しないとインスタンスはできあがらない。よって、BaseClass() 内で呼び出している Func() は、InheritClass のそれではない。コンストラクタ内の仮想メソッドは全く意図通りに動かない。
C#
class BaseClass
{
public BaseClass ()
{
Console.WriteLine ( "BaseClass ctor" );
Func ();
}
public virtual void Func ()
{
Console.WriteLine ( "BaseClass Func()" );
}
}
class InheritClass : BaseClass
{
public InheritClass ()
{
Console.WriteLine ( "InheritClass ctor" );
}
public override void Func ()
{
Console.WriteLine ( "InheritClass Func()" );
}
}
class Program
{
static void Main ( string[] args )
{
BaseClass c = new InheritClass ();
c.Func ();
}
}
実行結果
BaseClass ctor
InheritClass Func()
InheritClass ctor
InheritClass Func()
…。
と、とにかく呼ばない方がよい!…と思う。