我有这3个班级。
class A
{
public:
virtual void Func() = 0;
};
template<class T>
class B : public A
{
public:
void Func()
{
cout << "In B" << endl;
static_cast<T*>(this)->Func();
}
};
class C : public B<C>
{
public:
void Func()
{
cout << "In C" << endl;
}
};
而且,我这样做:
int main(int argc, char **argv)
{
A *a = new C;
a->Func();
return 0;
}
它打印:“在C”。
如果我这样做,
int main(int argc, char **argv)
{
B<C> *a = new C;
a->Func();
return 0;
}
再次打印“In C”
发生了什么事?
答案 0 :(得分:1)
您正在调用已重载此函数的C类对象的虚拟成员函数。它在C类中调用该函数。
此外,这不是CRTP,因为模板化的类B不会从类模板参数继承。
答案 1 :(得分:1)
Func
是虚拟的,a
是指向C
实例的指针,因此调用C
的{{1}}版本。
答案 2 :(得分:0)
代码不完整,添加#include和“using namespace std;”。更重要的是,通过删除A中的虚函数声明,您可以获得所需的行为。 一般来说,使用CRTP的主要原因是让模板知道它接收的类型并避免进行虚拟调用(或者更好,避免使方法成为虚拟)。
template <typename T>
class ClassUsingSomething {
public:
void method1() {
// I need to call method2, I do this by casting, so it doesn't need to be virtual.
static_cast<T *>(this)->method2();
}
};
class A: public ClassUsingSomething<A> {
public:
void method2() {
//do something
}
};