Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用CRTP进行遗传_C++_Overloading_Crtp - Fatal编程技术网

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
    }
};