为什么我不能从基类的实例访问受保护的成员?

Cás*_*nan 11 c++

假设我有这段代码:

class foo{
  protected:
  int a;
};

class bar : public foo {
  public:
  void copy_a_from_foo(foo& o){
    a = o.a; // Error
  }
  void copy_a_from_bar(bar& o){
    a = o.a; // OK
  }
};

int main(){
  bar x;
  foo y;
  bar z;
  x.copy_a_from_foo(y);
  x.copy_a_from_bar(z);
}
Run Code Online (Sandbox Code Playgroud)

这里class bar有没有问题访问受保护的成员a来自同一类的其他实例,但是当我尝试做同样与基类的一个实例foo,编译器给我的错误,说a是受保护的.标准对此有何看法?

错误是

prog.cpp: In member function 'void bar::copy_a_from_foo(foo&)':
prog.cpp:3:7: error: 'int foo::a' is protected
   int a;
       ^
prog.cpp:9:11: error: within this context
     a = o.a;
Run Code Online (Sandbox Code Playgroud)

PS:我看过这个问题,但它并不完全相同:我正试图从派生类中访问受保护的成员.

R S*_*ahu 6

protected只能通过指向或派生类型的对象的引用来访问基类的成员.

如果你改变了

void copy_a_from_bar(bar& o){
  a = o.a;
}
Run Code Online (Sandbox Code Playgroud)

void copy_a_from_bar(bar& o){
  foo& foo_ref = o;
  a = o.a;        // OK. Accessing it through `bar&`
  a = foo_ref.a;  // Not OK. Accessing it through `foo&`
}
Run Code Online (Sandbox Code Playgroud)

你会看到同样的错误.

这个SO答案说明了为什么允许访问基类成员protected可能会破坏protected基类成员的状态.

说你有:

class baz : public foo
{
   void update_a(foo& f)
   {
      f.a = 20;
   }
};
Run Code Online (Sandbox Code Playgroud)

并使用:

bar x;
baz z;
z.update_a(x);
Run Code Online (Sandbox Code Playgroud)

如果允许,baz将能够更改成员的值bar.这是不好的.