指向具有受保护继承的基类方法的指针

时间:2019-05-16 13:48:54

标签: c++ inheritance

我有此代码:

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”来继承自“ Foo”

当我使用using并且可以直接致电操作员时,为什么不能这样做?有什么办法吗?

如果我将继承更改为公开,那么它将起作用。

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

2 个答案:

答案 0 :(得分:5)

  

当我使用过using并且可以直接调用operator时,为什么不能这样做?

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

因此,要转换为o声明的类型,需要在继承树下进行转换。这种转换必须检查目标类确实是从基类派生的,但这是不可访问的基类。

一种解决方法是给Bar一个成员函数,该成员函数返回该指针。在Bar范围内,转换将可以访问该基础。另外,这种转换需要static_cast

答案 1 :(得分:3)

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

代替使用using Foo::operator[],也许可以解决您的问题:

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