Первое не разрешено, потому что оно приводит к неоднозначным определениям. Во втором случае, хотя у вас есть и открытая, и приватная целочисленная переменная a
, вы скрыли A :: a внутри своего класса B. Компилятор неявно знает, что вы хотите, потому что есть способ явного доступа к скрытым переменным.
Я также считаю, что это сводится к мангалированию имен: спецификаторы хранилища не заканчиваются как часть реального имени. Однако я могу ошибаться.
Самый простой способ проиллюстрировать, почему одно разрешено, а другое - нет, это посмотреть, как компилятор скомпилирует функцию-член, использующую каждую переменную.
Внутри вашего класса b:
class b {
int a;
public:
int a;
void myMethod()
{
a = 10; //what a should the compiler use? Ambiguous, so the compiler sez BZZT.
}
}
Для 2-го примера:
class A
{
public:
int a;
}
class B: public A
{
private:
int a;
void someMethod()
{
a = 10; //implied that you are using B::a (which may be a programmer error)
}
}