An additional access check beyond those described earlier in 
[class.access]
is applied when a non-static data member or non-static member function is a
protected member of its naming class (
[class.access.base])
.
As described earlier, access to a protected member is granted because the
reference occurs in a friend or direct member of some class 
C.All other accesses involve a (possibly implicit) object
expression (
[expr.ref])
.In this case, the class of the object expression shall be
C or a class derived from 
C.[
Example 1: 
class B {
protected:
  int i;
  static int j;
};
class D1 : public B {
};
class D2 : public B {
  friend void fr(B*,D1*,D2*);
  void mem(B*,D1*);
};
void fr(B* pb, D1* p1, D2* p2) {
  pb->i = 1;                    
  p1->i = 2;                    
  p2->i = 3;                    
  p2->B::i = 4;                 
  int B::* pmi_B = &B::i;       
  int B::* pmi_B2 = &D2::i;     
  B::j = 5;                     
  D2::j = 6;                    
}
void D2::mem(B* pb, D1* p1) {
  pb->i = 1;                    
  p1->i = 2;                    
  i = 3;                        
  B::i = 4;                     
  int B::* pmi_B = &B::i;       
  int B::* pmi_B2 = &D2::i;     
  j = 5;                        
  B::j = 6;                     
}
void g(B* pb, D1* p1, D2* p2) {
  pb->i = 1;                    
  p1->i = 2;                    
  p2->i = 3;                    
}
 — 
end example]