如何从派生类访问基类中的受保护方法?

Ber*_*set 9 c++ protected derived-class

这是一个让我烦恼的代码示例:

class Base {
  protected:
    virtual void foo() = 0;
};

class Derived : public Base {
  private:
    Base *b; /* Initialized by constructor, not shown here
                Intended to store a pointer on an instance of any derived class of Base */

  protected:
    virtual void foo() { /* Some implementation */ };
    virtual void foo2() {
      this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
    }
};
Run Code Online (Sandbox Code Playgroud)

您如何访问受保护的覆盖功能?

谢谢你的帮助.:O)

Bar*_*nau 10

基类中的受保护成员只能由当前对象访问.
因此,您可以拨打电话this->foo(),但不允许您拨打电话this->b->foo().这与是否Derived提供实现foo无关.

这种限制背后的原因是,它可以很容易地规避受保护的访问.你只需要创建一个类Derived,然后突然你也OtherDerived可以访问外部人员无法访问的其他类(如)的部分内容.

  • 请不要将其视为安全漏洞.访问修饰符不提供任何安全性,如果需要数据,则可以只读取内存位置. (8认同)

Jon*_*ood 6

通常,您可以使用Base::foo(),它指的是当前实例的基类.

但是,如果您的代码需要按照您尝试的方式执行并且不允许,那么您需要将foo()设为public或使Derived成为Base的朋友.


Cle*_*aff 5

一种解决方案是声明一个静态受保护函数,将Base调用重定向到私有/受保护函数(foo在示例中)。

可以说:

class Base {
protected:
    static void call_foo(Base* base) { base->foo(); }
private:
    virtual void foo() = 0;
};

class Derived : public Base {
private:
    Base* b;
protected:
    virtual void foo(){/* Some implementation */};
    virtual void foo2()
    {
        // b->foo(); // doesn't work
        call_foo(b); // works
    }
};
Run Code Online (Sandbox Code Playgroud)

这样,我们就不会破坏封装,因为 的设计者Base可以做出显式选择以允许所有派生类相互调用foo,同时避免放入foo公共接口或显式地将 的所有可能子类转变Base为友元。

此外,无论foo是虚拟的还是非虚拟的,或者是私有的还是受保护的,此方法都有效。

是上面代码的运行版本的链接,这里是相同想法的另一个版本,但有更多的业务逻辑。