针对函数重写的CRTP 在虚拟函数的替换中,经常建议使用CRP来避免C++中的动态调度。但是,不能使用简单的基类指针访问派生类对象(实际上不知道派生对象的类型)

针对函数重写的CRTP 在虚拟函数的替换中,经常建议使用CRP来避免C++中的动态调度。但是,不能使用简单的基类指针访问派生类对象(实际上不知道派生对象的类型),c++,performance,crtp,overriding,C++,Performance,Crtp,Overriding,在这种情况下,我想知道CRTP对函数重写有什么好处。为了解释我的观点,我准备了以下示例: CRTP定义颜色组基类和两个专门化类的方法: template <typename D> class CG { public: void Green() { GetD()->GreenColor(); } void White() { GetD()->WhiteColor(); } public: void GreenColor() { std::co

在这种情况下,我想知道CRTP对函数重写有什么好处。为了解释我的观点,我准备了以下示例:

CRTP定义颜色组基类和两个专门化类的方法:

template <typename D>
class CG
{
public:
    void Green() { GetD()->GreenColor(); }
    void White() { GetD()->WhiteColor(); }    
public:
    void GreenColor() { std::cout << "This is a simple Green color" << std::endl; }
    void WhiteColor() { std::cout << "This is a simple White color" << std::endl; }

private:
    D* GetD() { return static_cast<D*>(this); }
};

class ColorGroup1 : public CG<ColorGroup1>
{
private:
    friend class CG<ColorGroup1>;
    void GreenColor() { std::cout << "ColorGroup1: This is Green Shade 1" << std::endl; }
};

class ColorGroup20 : public CG
{
public:
    void WhiteColor() { std::cout << "ColorGroup20: This is White Shade 20" << std::endl; }
};   
所以我的问题是:

  • CRTP是否提供了函数重写所不提供的任何其他优势
  • 我的假设是否正确,即这两种方式提供相同/相似的性能
  • 如果给我一个选择,我会选择函数重写。你会选择什么?为什么

  • 非常感谢您抽出时间。

    首先,我不同意我们需要虚拟函数来覆盖函数。基类函数可以在具有相同签名的派生类中重写。其次,为了澄清,我的问题不是关于通过基类指针访问对象,而是想知道为什么我们不能简单地重写上面示例中给出的功能,并用更少的代码实现与CRTP示例相同的结果。使用相同的签名重写非虚方法不是重写,它藏起来了。这两件事在很多方面确实是不同的。而且,第三点主要是基于观点的。好的。它不是压倒性的,而是隐藏的。但这个问题仍然没有答案。你们有谁看到这两种方法的优点/缺点吗?首先,我不同意我们需要虚拟函数来覆盖函数。基类函数可以在具有相同签名的派生类中重写。其次,为了澄清,我的问题不是关于通过基类指针访问对象,而是想知道为什么我们不能简单地重写上面示例中给出的功能,并用更少的代码实现与CRTP示例相同的结果。使用相同的签名重写非虚方法不是重写,它藏起来了。这两件事在很多方面确实是不同的。而且,第三点主要是基于观点的。好的。它不是压倒性的,而是隐藏的。但这个问题仍然没有答案。你们有谁看到这两种方法的优点/缺点吗。
    class CG
    {
    public:
        void Green()  { std::cout << "This is a simple Green color"  << std::endl; }
        void White()  { std::cout << "This is a simple White color"  << std::endl; }
    };
    
    class ColorGroup1 : public CG
    {
    public:
        void Green() { std::cout << "ColorGroup1: This is Green Shade 1" << std::endl; }
    };
    
    class ColorGroup20 : public CG
    {
    public:
        void White() { std::cout << "ColorGroup20: This is White Shade 20" << std::endl; }
    };
    
    int main()
    {
        ColorGroup1 w;
        w.Green();
        w.White();
    
        std::cout << std::endl;
    
        ColorGroup20 p;
        p.Green();
        p.White();
    
        return 0;
    }
    
    ColorGroup1: This is Green Shade 1
    This is a simple White color
    
    This is a simple Green color
    ColorGroup20: This is White Shade 20