好的,所以我在这里采取了一种修改后的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
是静态的并不重要我注意到了。
答案 0 :(得分:2)
在第一种情况下,bar
是虚函数,foo
通过指向A
的指针访问它,从而调用函数指针和指定的Vtable索引作为类{布局' {1}}。因此它有效。
但是,在第二种情况下,A
显式调用了它无法访问的不同类的非虚函数。 A::foo
不是B::bar
的虚拟重载 - 它是完全不同的无关函数。
因此,制作A::bar
是你能得到的最好的,我担心。