用受保护的继承指向基类方法

Pointer to base class method with protected inheritance

本文关键字:基类 类方法 继承 受保护      更新时间:2023-10-16

我有此代码:

class Foo
{
public:
    int x = 4;
    int & operator[](size_t index) { return x; }
};
class Bar : protected Foo
{
public: 
    using Foo::operator[];
    Bar () { x++; }
};
int main(int agrc, char ** argv)
{
    typedef int &(Bar::*getOp)(size_t index);
    Bar b;
    auto bVal = b[4];
    getOp o = &Bar::operator[]; 
    auto bVal2 = (b.*o)(7);
}

但是,我无法编译,因为

错误c2247:'foo'无法访问,因为" bar'使用" protected'

当我使用using并且可以直接调用操作员时,为什么这是不可能的?有什么办法吗?

如果我将继承更改为公众,则可以正常工作。

注意:这只是较大类的示例。我不想使用公共继承,因为我不想做Foo f = Bar(),因为在Bar中,我隐藏了父方法(我没有使用虚拟(。

当我使用使用并可以直接调用操作员时,为什么这是不可能的?

使用声明使您可以访问 name operator[]。但这不会改变成员的类型。它留下来 int &(Foo::*)(size_t)。注意Foo

因此,转换为声明的 o的类型需要向继承树进行转换。此转换必须检查目标类的确是从基数得出的,但这是一个无法接近的基础。

围绕它的一种方法是使Bar返回该指针的成员函数。在Bar的范围内部,转换将可以访问基数。另外,这种转换需要static_cast

一旦基类Foo无法访问,就不允许此转换。

而不是使用using Foo::operator[],也许这可以解决您的问题:

int& operator[](size_t index) { // now a Bar::operator[], not Foo:: anymore
    return Foo::operator[](index);
}