C++03 3.2.2 ...An object or non-overloaded function is used if its name appears in a potentially-evaluated expression. A virtual member function is used
C++03 3.2.2
[class.abstract]: "A pure virtual function need be defined only if called with, or as if with (12.4), the qualified-id syntax (5.1)."
Your A::f is called by B::f, so there must be a single definition of A::f.
A::f
B::f