This thread was inspired by
http://www.cplusplus.com/forum/general/1363/ where, frankly, we all got rather confused. There were a variety of issues that I think merit further discussion though. I'm pretty sure I was as much part of the problem in that thread as anyone, so here's my attempt at hacking through the undergrowth and making amends.
This question is modelled partially on Herb Sutter's marvelous series "Guru of the Week". (
http://www.gotw.ca/gotw/index.htm) Obviously, I'm not a guru, but I thought his question style was a good one for prompting discussion. Again obviously, I think I know the answers, but I'm probably wrong. (Or at least my answers are incomplete) That's the point.
Anyway, onwards...
Consider the following code: (A complete, legal, and compilable program! Go on, try it)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include <iostream>
using namespace std;
struct Base
{
// private:
void f(char)
{
cout << "Base::f(char);\n";
}
};
struct Derived : Base
{
// using Base::f;
void f(int)
{
cout << "Derived::f(int);\n";
}
};
int main()
{
Base b;
Derived d;
// Call f using an int as the argument
b.f(10);
d.f(10);
// Call f using a char as the argument
b.f('a');
d.f('a');
}
|
1. What does it print and *why* ? (Also, why does C++ choose to do it this way?)
2. Uncomment line 18. Again, what does it print and why?
3. Uncomment line 7. What happens? Why is this the right thing to do?
4. What can we say about the order of name lookup, overload resolution, and the application of access control rules? Why is this important?
Don't answer straight away - try the code out, see if your compiler does what you expect.
(IMPORTANT NOTE: I believe there is more to this than meets the eye - particularly considering why C++ is they way it is and also the interactions between using directives and encapsulation)