The correct answer has already been given by @songyuanyao.
Checking access specifiers at the last was designed by the C++ Standard Committee.
Had it not been so, the following things would have occurred :
- If one modifies their code in future and change the access specifier of their functions, it may break the compilation of the dependent classes.
- More horrible yet, you may start calling a totally unrelated function, and would remain oblivious..!!
Let us assume that access specifiers prevent a function from participating in overload resolution, then :
class A{
public:
void fn() { cout << "1"; }
};
class B{
void fn() { cout << "2"; }
};
class C: public A, public B {};
int main(){
C objc;
objc.fn(); // A::fn() is being invoked
return 0;
}
Now we modify the code:
class A{
void fn() { cout << "1"; }
};
class B{
public:
void fn() { cout << "2"; }
};
Nothing else has been touched, and suddenly
objc.fn(); // B::fn() is being invoked
The caller of your function has no idea that his underlying function is not the same anymore.
This is blasphemy !!
To prevent all such mishaps from happening, the Standard Committee took this design decision.