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可以访问外部人员无法访问的其他类(如)的部分内容.
通常,您可以使用Base::foo(),它指的是当前实例的基类.
但是,如果您的代码需要按照您尝试的方式执行并且不允许,那么您需要将foo()设为public或使Derived成为Base的朋友.
一种解决方案是声明一个静态受保护函数,将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是虚拟的还是非虚拟的,或者是私有的还是受保护的,此方法都有效。
这是上面代码的运行版本的链接,这里是相同想法的另一个版本,但有更多的业务逻辑。