-1

我正在将这样的代码从 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'

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

4

1 回答 1

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
    ...
}

这里的文字虽然不是直接来自标准,但更清楚。

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

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

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

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

但是,同样的事情似乎不适用于 clang。

于 2013-02-15T10:04:23.830 回答