Names in derived class hides names in base class. In other words, your function "foo" in your derived class hides the foo function in your base class even though they take different types of parameters. This is the reason you get an error when you call D.foo("aaa"). You resolve this in two ways. You can either use a using declaration in your derived class like the one below.
1 2 3 4 5 6 7 8
class derived: public base{
public:
using base::foo;int foo(int a) {cout<<"derived, foo, int \n"; return 2;}
derived(){}
~derived(){}
};
(or)
you could define another foo function in your derived class that takes a string parameter but implement by forwarding the call to the base class implementation of foo. You can call the base class version of foo using base::foo(string).
Scott Meyers's Effective C++ book discusses this issue in detail.
Names in derived class hides names in base class. In other words, your function "foo" in your derived class hides the foo function in your base class even though they take different types of parameters.
Above contradict common sense and in this aspect, Java work what we expected.
Scott Meyers book is an essential read for anyone interested in those more in-depth C++ topics.