C++ 用CRTP进行遗传
我有这三门课C++ 用CRTP进行遗传,c++,overloading,crtp,C++,Overloading,Crtp,我有这三门课 class A { public: virtual void Func() = 0; }; template<class T> class B : public A { public: void Func() { cout << "In B" << endl; static_cast<
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;
}
};
它会打印:“在C中”
如果我这样做
int main(int argc, char **argv)
{
B<C> *a = new C;
a->Func();
return 0;
}
int main(int argc,char**argv)
{
B*a=新的C;
a->Func();
返回0;
}
它再次打印“C”
发生了什么?您正在调用一个C类对象的虚拟成员函数,该对象重载了该函数。它调用类C中的函数
此外,这不是CRTP,因为模板化类B不从类模板参数继承。
Func
是虚拟的,a
是指向C
实例的指针,因此调用C
的Func
版本。如果代码不完整,请添加“include”和“using namespace std;”。更重要的是,通过删除A中的虚拟函数声明,可以获得所需的行为。
通常,使用CRTP的主要原因是让模板知道它接收到的类型,并避免执行虚拟调用(或者更好,避免使方法虚拟化)
模板
用某物上课{
公众:
void method1(){
//我需要调用method2,我通过强制转换来实现,所以它不需要是虚拟的。
静态_cast(this)->method2();
}
};
A类:使用某物的公共类{
公众:
void方法2(){
//做点什么
}
};
您希望它打印什么?在第二种情况下是“在B中”,然后是“在C中”?代码不会编译。修复B::Func中的静态强制转换或解释要实现的功能。此代码编译。。。g++(SUSE Linux)4.3.2原始代码(在修复之前)缺少很多必要的东西,所以很难说最初的意思。也许CRTP的东西也不小心丢失了…你说这不是CRTP是什么意思?你的意思是B应该从C继承吗?不。CRPT意味着B应该从T继承。但是在第二种情况下,a的类型是B*,具有虚拟函数,指针的类型无关紧要。指向对象的动态类型很重要,在这两种情况下都要创建一个C。@nakiya:B*是从a派生的。a::Func是虚拟的,所以B::Func是虚拟的,C::Func是虚拟的。
int main(int argc, char **argv)
{
B<C> *a = new C;
a->Func();
return 0;
}
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
}
};