我有此代码:
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)。
答案 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);
}