C ++保护的成员继承

时间:2016-02-29 14:31:16

标签: c++ access-control

我的问题是为什么我不能通过指向基类的指针在派生类中调用受保护的虚拟成员函数,除非将派生类声明为基类的朋友?

例如:

#include <iostream>

class A {
  friend class C;  // (1)
protected:
  virtual void foo() const = 0;
};

class B : public A {
  void foo() const override { std::cout << "B::foo" << std::endl; }
};

class C : public A {
  friend void bar(const C &);
public:
  C(A *aa) : a(aa) { }
private:
  void foo() const override {
    a->foo();       // (2) Compile Error if we comment out (1)
    //this->foo();  // (3) Compile OK, but this is not virtual call, and will cause infinite recursion
    std::cout << "C::foo" << std::endl;
  }
  A *a;
};

void bar(const C &c) {
  c.foo();
}

int main() {
  B b;
  C c(&b);
  bar(c);

  return 0;
}

输出

B::foo
C::foo

在上面的代码中,我想通过类foo()的成员a调用虚函数C(在编译时不是通过this的静态绑定),但如果我不将C作为A的朋友,那么这个电话就是非法的。

我认为C是从A继承的,因此它可以访问protected的{​​{1}}成员,但为什么它实际上不会发生?

1 个答案:

答案 0 :(得分:5)

C可以访问其自己的基类的受保护成员,但不能访问任何其他A的成员。

在您的示例中,参数aB没有访问权限的完全不相关的类C的一部分(除非您将其作为朋友)。