First, B is actually a nested class, and, oddly enough, private members of nested classes can access the outer class. Otherwise, it would be even legal to do ((AB)a).method2(); (the converse is also true. B can also access private members in A.)
However, to answer your real question, the reason why a.method2(); calls the private method in A, lies in the fact that private methods are not virtual, because they cannot be overridden at all. (How can they be if class inheritance doesn't even have to know about them?) Thus, they are bound at compile time, which means using a declared variable type. A a declared as A, but (AB)a is executed when compiling to B. Thus, your first call uses the private method from A, and your second call uses the private method from B.
It is bizarre that the facts in these two paragraphs do not interact with each other. One would expect that since the nested class “knows” about the outer members of the outer class, redefinition may be possible. But this is not so. Private functions are never displayed in vTable and can never be overridden.
source share