2011-01-12 110 views
8

下面是代码样本惹恼我:如何从派生类访问基类中的受保护方法?

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' */ 
    } 
}; 

如何访问到受保护的overrided功能?

感谢您的帮助。 :o)

+7

我不认为你的实施是完全正确的。为什么你有一个Base的实例作为成员变量? this-> b-> foo()会尝试调用一个纯粹的虚拟方法。 – GWW 2011-01-12 18:26:34

+1

这个程序不应该编译。你不能实例化一个抽象类....除非`b`指向从`Base`派生的其他类的实例。 – 341008 2011-01-12 18:34:58

+0

我省略了精确性:Derived :: b属性用于存储基类 – 2011-01-13 10:44:15

回答

8

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

这个限制背后的原因是,否则它很容易绕过受保护的访问。您只需创建一个类似Derived的课程,并且突然间您还可以访问其他类别的部分课程(如OtherDerived),这些课程本应该是外界无法访问的。

5

通常情况下,你可以使用Base::foo()来实现,它指的是当前实例的基类。但是,如果您的代码需要按照您尝试的方式进行操作,并且不允许,那么您需要将foo()公开或派生为Base的朋友。

0

您可以使用scope运算符(Base :: foo())显式调用基函数。但是在这种情况下,Base类没有定义foo(它是纯虚拟的),所以当你说this->b->foo();时,实际上没有函数可以执行,因为b是指向Base而不是Derived的指针。

0

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

---从哪里来?

您只能通过继承访问受保护的成员(除了同一类的方法外)。例如说你有一个,它继承自Derived,那么Derived1的对象可以调用foo()

编辑:MSDN article受保护的访问说明符。

1

这有点脆弱,但是您在这里定义的类不会工作吗?

virtual void foo2() { 
    reinterpret_cast<Derived *>(this->b)->foo(); 
} 

reinterpret_cast指向基础对象的VTABLE,并通过此成员访问器调用它。

2

一种解决方案是在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 
    } 
}; 

通过这种方式,我们不打破封装,因为Base设计者可以做出明确的选择,让所有派生类调用foo对方,同时避免把foo进入公共界面或明确地将所有可能的Base的子类变为朋友。

此外,无论foo是否为虚拟,或者是私有的还是受保护的,此方法都可以工作。

Here是一个链接到上面的代码的运行版本和here另一个版本的相同的想法多一点的业务逻辑。

相关问题