通过 CRTP 进行继承

发布于 2024-08-22 12:51:46 字数 827 浏览 7 评论 0原文

我有这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;  
}  

它打印:“In C”。

如果我这样做,

int main(int argc, char **argv)  
{  
    B<C> *a = new C;  
    a->Func();  

    return 0;  
}  

它会再次打印“In C”,

这是怎么回事?

I have these 3 classes.

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

And, I do this:

int main(int argc, char **argv)  
{  
    A *a = new C;  
    a->Func();  

    return 0;  
}  

And it prints : "In C".

If I do this,

int main(int argc, char **argv)  
{  
    B<C> *a = new C;  
    a->Func();  

    return 0;  
}  

It again prints "In C"

What is going on?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

待"谢繁草 2024-08-29 12:51:46

您正在调用一个重载了该函数的 C 类对象的虚拟成员函数。它调用类 C 中的函数

。此外,这不是 CRTP,因为模板化类 B 不继承自类模板参数。

You're calling a virtual member function of a class C object who has overloaded this function. It calls the function in class C.

Furthermore, this is not CRTP as the templated class B does not inherit from the class template parameter.

愚人国度 2024-08-29 12:51:46

Func 是虚拟的,a 是指向 C 实例的指针,因此 C版本>Func 被调用。

Func is virtual, a is a pointer to an instance of C, so C's version of Func is called.

错々过的事 2024-08-29 12:51:46

代码不完整,添加#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
    }
};

The code is not complete, add #include and "using namespace std;". More importantly, you get the desired behaviour by removing the virtual function declaration in A.
In general, the main reason to use CRTP is to let the template know the type it receives and avoid doing a virtual call (or better, avoid making the method virtual).

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
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文