Here’s a little Object-Oriented question: If I have a function f in my base class, say that takes an integer, and I write an overload of that function in a derived class that takes something different, can I still call the original function that was inherited from the base class? The answer might surprise you.
A Simple Base Class
Let’s start with some plain vanilla C++, no CLR in sight. Here’s a base class:
class A { protected: int i; char* s; public: A():s(NULL),i(-1) {} void f(int ii) {i=ii;s=new char(0);} void f(char* ss) {i=0; if (s) delete s; s= new char[strlen(ss)];strcpy(s,ss);} void report () { cout << i << " " << s << endl;} };
While it isn’t likely to win any contest for usefulness, and the second overload of f is a bit long for inlining, it will do. Clearly, you can use this class like this:
A a; a.f(1); a.report(); a.f("Hello"); a.report();
Deriving and Overloading
What happens to these overloads of f when I write a base class, B?
class B: public A { public: void nothing() {;} void f(int ii, char* ss){i=ii; if (s) delete s; s= new char[strlen(ss)];strcpy(s,ss);} };
The answer, and this surprises many people, is that they seem to disappear. Here’s some calling code:
B b; b.nothing(); b.f(2); b.report(); b.f("Yoo-Hoo!"); b.report();
This code compiles only when B::f(int, char*) is commented out. With that overload in place, this code produces messages such as 'B::f' : function does not take 1 arguments. You can call only the two-parameter version of f():
b.f(3,"Oops"); b.report();
Of course, if you absolutely need to get to the base class function, you can, but you have to be explicit about it:
b.A::f(4); b.report();
Managed Classes
What happens if A and B become managed classes in a managed console application? (For simplicity, let’s keep working with int and char*, but I will replace the iostream with System::Console equivalents.)
using namespace System; __gc class A { protected: int i; char* s; public: A():s(NULL),i(-1) {} void f(int ii) {i=ii;s=new char(0);} void f(char* ss) {i=0; if (s) delete s; s= new char[strlen(ss)];strcpy(s,ss);} void report () { Console::Write(__box(i)); Console::Write(" "); Console::WriteLine(s);} }; __gc class B: public A { public: void nothing() {;} void f(int ii, char* ss){i=ii; if (s) delete s; s= new char[strlen(ss)];strcpy(s,ss);} };