class Base { public: virtual void Foo(); } class Derived : public Base { public: virtual void Foo(); }
0:000> dt der Local var @ 0xcfe60 Type Derived +0x000 __VFN_table : 0x008e10cc 0:000> dps 0x008e10cc l1 008e10cc 008e11f0 testsize!Derived::Foo
class Base { public: virtual void Foo(Bar* PBar); } class Derived : public Base { public: virtual void Foo(); }
0:000> dt der Local var @ 0x13fd38 Type Derived +0x000 __VFN_table : 0x001810cc Exact matches: 0:000> dps 0x001810cc l2 001810cc 00181250 testsize!Base::Foo 001810d0 00181200 testsize!Derived::Foo
The first technique is to change the return type of the function to refactor without changing the parameters themselves and then recompiling the project. This works because the rules for C++ name overloading allow for differences in the function's parameters, but if the parameters are the same, you cannot differentiate on return type. The error will be emitted in the class's implementation. So if you change Base::Foo to ULONG Foo();, the compiler will give you an error like this for every derived class which overrides Base::Foo()
main.cpp(7) : error C2555: 'Derived::Foo': overriding virtual function return type differs and is not covariant from 'Base::Foo'."
The second technique is to change the Base::Foo() to a pure virtual fuction in addition to changing the parameters. So, now Base::Foo() is declared as void Foo(Bar* PBar) =0;. Now for every class which is not an abstract base class itself, the compiler will emit an error wherever you try to instantiate the class, getting an error like this
main.cpp(11) : error C2259: 'Derived' : cannot instantiate abstract class
I personally prefer the first method because it is less error prone and I like to see compiler errors at the site of the implementation and not at the site of its use.