通常建议使用CRTP来避免C ++中的动态调度,以替代虚函数。但是,无法使用简单的基类指针访问派生类对象(实际上不知道派生对象的类型)。
在这种情况下,我想知道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:
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; }
};
现在我可以在两个不同的程序中使用以下代码,一个使用CRTP定义的类,另一个使用函数重写。
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
所以我的问题是:
非常感谢你的时间。