現在、動的バインディングと仮想関数について学んでいます。これは Accelerated C++ の第 13 章からのものです。
[...] その決定は実行時に行いたいと考えています。つまり、関数に渡されるオブジェクトの実際のタイプに基づいて、システムが正しい関数を実行するようにする必要があります。これは、実行時にのみわかります。
コンパイル時にオブジェクトの型が不明になる可能性があるという考え自体がわかりません。ソースコードを見れば一目瞭然ですよね?
現在、動的バインディングと仮想関数について学んでいます。これは Accelerated C++ の第 13 章からのものです。
[...] その決定は実行時に行いたいと考えています。つまり、関数に渡されるオブジェクトの実際のタイプに基づいて、システムが正しい関数を実行するようにする必要があります。これは、実行時にのみわかります。
コンパイル時にオブジェクトの型が不明になる可能性があるという考え自体がわかりません。ソースコードを見れば一目瞭然ですよね?
全くない。次の例を検討してください。
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { std::cerr << "In B::f()\n"; }
};
struct C : A {
virtual void f() { std::cerr << "In C::f()\n"; }
};
static void f(A &a)
{
a.f(); // How do we know which function to call at compile time?
}
int main(int,char**)
{
B b;
C c;
f(b);
f(c);
}
グローバル関数f
がコンパイルされると、どの関数を呼び出す必要があるかを知る方法がありません。実際、毎回異なる関数を呼び出す必要があります。で初めてf(b)
呼び出す場合は を呼び出す必要がB::f()
あり、2 回目に呼び出す場合はf(c)
を呼び出す必要がありますC::f()
。
派生オブジェクトを指す基本クラスへのポインターがあるとします
Base *pBase = new Derived;
// During compilation time, compiler looks for the method CallMe() in base class
// if defined in class Base, compiler is happy, no error
// But when you run it, the method call gets dynamically mapped to Derived::CallMe()
// ** provided CallMe() is virtual method in Base and derived class overrides it.
pBase->CallMe(); // the actual object type is known only during run-time.