好的,我在这里采取一种修改的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是静态的并不重要我注意到了.
第一种情况bar是虚函数,并foo通过指针访问它,从而A调用函数指针和 Vtable 的指定索引,按 class 进行布局A。这样就可以了。
但是,在第二种情况下,A::foo从它无法访问的不同类中显式调用非虚函数。B::bar不是虚拟重载A::bar- 它是完全不同的不相关函数。
因此,friend class A;恐怕制作是你能得到的最整洁的。
| 归档时间: |
|
| 查看次数: |
659 次 |
| 最近记录: |