CRTP奇异递归模板技术学习笔记

MirrorYuChen
MirrorYuChen
发布于 2024-12-02 / 18 阅读
0
0

CRTP奇异递归模板技术学习笔记

CRTP(Curiously Recurring Template),奇异递归模板

​ CRTP是一种C++设计方法,类X派生自一个模板参数为Z的类模板Y,并且Y实例化为模板参数 Z=X,如:

template <class Z>
class Y {};

class X : public Y<X> {};

1.简单例子

​ CRTP可用于实现“编译时多态”,当基类暴露一个接口,派生类实现这样一个接口:

#include <iostream>

template<class Derived>
class Base {
public:
  void name() {
    static_cast<Derived*>(this)->Impl();
  }
};

class D1 : public Base<D1> {
public:
  static void Impl() {
    std::cout << "D1::Impl()" << std::endl;
  }
};

class D2 : public Base<D2> {
public:
  static void Impl() {
    std::cout << "D2::Impl()" << std::endl;
  }
};

int main() {
  D1 d1;
  d1.name();
  D2 d2;
  d2.name();
  return 0;
}

​ 输出结果:

D1::Impl()
D2::Impl()

​ 最核心的代码 static_cast<Derived*>(this)->Impl();,这里就是将父类指针转换成子类指针,然后调用子类的实现方法。

2.不暴露实现

#include <iostream>

template<class Derived>
class Base {
public:
  void name() {
    static_cast<Derived*>(this)->Impl();
  }
};

class D1 : public Base<D1> {
private:
  friend Base<D1>;
  static void Impl() {
    std::cout << "D1::Impl()" << std::endl;
  }
};

class D2 : public Base<D2> {
private:
  friend Base<D2>;
  static void Impl() {
    std::cout << "D2::Impl()" << std::endl;
  }
};

int main() {
  D1 d1;
  d1.name();
  D2 d2;
  d2.name();
  return 0;
}

​ 输出结果:

D1::Impl()
D2::Impl()

3.CRPT好处

  • (1) 静态多态CRTP实现静态多态,无需使用虚函数,静态绑定,无运行时开销;
  • (2) 类型安全CRTP提供了类型安全的多态性,通过模板参数传递具体子类类型,编译器能确保类型匹配,避免了传统向下转换可能引起的类型错误;
  • (3) 灵活接口设计CRTP允许父类定义公共接口,并要求子类实现具体操作,这使得基类能提供通用接口,而具体实现细节留给派生类,其实也就是多态了。

4.参考资料


评论