从受限制的(静态)成员函数访问受保护的成员

时间:2012-01-27 20:23:16

标签: c++ templates

好的,所以我在这里采取了一种修改后的CRTP路线,以避免虚拟功能查找。但我无法理解它给我的一个错误......

所以我试图翻译:

class A
{
public:
    static void foo(A *pA)
    {
        pA->bar();
    }

protected:
    virtual void bar()
    {
        TRACE0(_T("A::bar\n"));
    }
};

class B : public A
{
protected:
    virtual void bar()
    {
        TRACE0(_T("B::bar\n"));
    }
};

按预期工作:

class A
{
public:
    template <class T>
    static void foo(T *pT)
    {
        pT->bar();
    }

protected:
    void bar()
    {
        TRACE0(_T("A::bar\n"));
    }
};

class B : public A
{
protected:
    void bar()
    {
        TRACE0(_T("B::bar\n"));
    }
};

给出错误:

error C2248: 'B::bar' : cannot access protected member declared in class 'B'
see declaration of 'B::bar'
see declaration of 'B'
see reference to function template instantiation 'void A::foo<B>(T *)' 
being compiled with
[
    T=B
]

现在我知道,通过将friend class A;添加到B类可以很容易地解决这个问题,但这不是很整洁。是不是有另一种方式?

编辑:示例用法:

B b;
b.foo<B>(&b);

编辑#2:成员函数foo是静态的并不重要我注意到了。

1 个答案:

答案 0 :(得分:2)

在第一种情况下,bar是虚函数,foo通过指向A的指针访问它,从而调用函数指针和指定的Vtable索引作为类{布局' {1}}。因此它有效。

但是,在第二种情况下,A显式调用了它无法访问的不同类的非虚函数。 A::foo不是B::bar的虚拟重载 - 它是完全不同的无关函数。

因此,制作A::bar是你能得到的最好的,我担心。