Ordinarily functions are selected at compile time according to the static type of the caller object. e.g.
class X {
public:
void f();
};
class Y : public X {
public:
void f(); // identical signature to X's function f
};
class Z : public X {
public:
...
};
For these objects:
X x; Y y; Z z;the following calls are valid:
x.f() calls X's function f,
y.f() calls Y's function f, and
z.f() calls X's function f, which Z inherits
When a pointer to type X points to an object of type Y, or of type Z, the static type is still used, according to the sub-type principle, i.e. with
X* px1 = &x; // px1 points to an X X* px2 = &y; // px2 points to a Y X* px3 = &z; // px3 points to a Zthe three calls:
px1->f(), px2->f(), and px3->f()
still call X's function f, even though, in the second and third cases, px2 and px3 actually point to
objects of type Y and Z respectively.
This can be altered if the keyword virtual is used on the function declaration in the base class, X:
class X {
public:
virtual void f(); // needs to be repeated in derived classes
};
Now, whereas the calls for objects x, y and z remain unchanged, the situation
with pointers is different:
px1->f();still calls X's function (the function is not really virtual-- it still has a body!), but
px2->f();now calls Y's function, the function of the object actually pointed to by px2. Also
px3->f();calls X's function, but this time because Z (the type of the object pointed to by px3) inherits it from X.
This selection is done at run-time, and is called dynamic, or late binding.
Copyright © 2003 Roger Hartley