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

dem*_*rge 7 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"));
    }
};
Run Code Online (Sandbox Code Playgroud)

按预期工作:

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"));
    }
};
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

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
]
Run Code Online (Sandbox Code Playgroud)

现在我知道,这很容易通过添加friend class A;到B级来修复,但这不是很整洁.不是有另一种方式吗?

编辑:示例用法:

B b;
b.foo<B>(&b);
Run Code Online (Sandbox Code Playgroud)

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

Kri*_*izz 2

第一种情况bar是虚函数,并foo通过指针访问它,从而A调用函数指针和 Vtable 的指定索引,按 class 进行布局A。这样就可以了。

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

因此,friend class A;恐怕制作是你能得到的最整洁的。