The first isn't allowed because it leads to ambiguous definitions. In the 2nd, although you do have both a public and a private a
integer variable, you've hidden A::a inside your B class. The compiler knows implicitly what you want because there is a way to explicitly access a hidden variables.
I also believe that it boils down to name mangaling: storage specifiers don't end up as part of the actual name. I could be wrong on this however.
The easiest way to illustrate why one is allowed and why the other isn't is to look at how the compiler would compile a member function that uses each variable.
Inside your class b:
class b {
int a;
public:
int a;
void myMethod()
{
a = 10; //what a should the compiler use? Ambiguous, so the compiler sez BZZT.
}
}
For the 2nd example:
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)
}
}