如何指定对隐藏的受保护基类成员的访问权限?

时间:2013-02-15 09:14:47

标签: c++ visual-studio-2010 visual-studio migration

我正在将这样的代码从MS VS6迁移到VS2010:

class A
{
protected:
    typedef void (A::*X_t)(int x);
    virtual void CallX(X_t x) {}
    virtual void X() {}
    virtual void X(int x) {}
};

class B: public A
{
protected:
    virtual void X()
    {
        this->CallX(&A::X);
    }    
};

这是在MS VS6中编译的,但在VS2010中它在

上失败
error C2248: 'A::X' : cannot access protected member declared in class 'A'

有没有办法摆脱这个错误?

1 个答案:

答案 0 :(得分:2)

如果你看一下标准,11.4 / 1,说实话,语言会让我感到困惑。但是这个例子很清楚:

class B {
protected:
    int i;
    static int j;
};

class D1 : public B {
};

class D2 : public B {
    friend void fr(B*,D1*,D2*);
    void mem(B*,D1*);
};

... irrelevant stuff snipped

void D2::mem(B* pb, D1* p1) {
    ...
    int B::* pmi_B = &B::i; // ill-formed  *****this*****
    int B::* pmi_B2 = &D2::i; // OK
    ...
}

文本here虽然不直接来自标准,但更为明确。

  

如果引用a中基类A的受保护非静态成员x   朋友或派生类B的成员函数,您必须访问x   通过指向,引用或从中派生的类的对象   答:但是,如果您正在访问x以创建指向成员的指针,那么   必须使用命名派生的嵌套名称说明符限定x   B级。

所以,如果我的理解在这里是正确的,那么Visual Studio拒绝这一点是正确的。

要修复它,我不确定这是否正确,但它似乎在VS2012中解决了我的问题:

 this->CallX(&B::A::X);

然而,同样的事情似乎不适用于clang。