C++ 中的自递归模板模式 (CRTP)

2025年5月14日 | 阅读 4 分钟

在本文中,我们将通过几个示例讨论 C++ 中的奇异递归模板模式 (CRTP)。

什么是奇异递归模板模式?

奇异递归模板模式是一种编程技巧,它使用基于模板的继承来实现静态多态。在这种模式中,一个基类模板由一个派生类参数化,其中派生类使用自身作为模板参数继承自该基类。通过使用此模板,基类可以在编译时访问和操作派生类的成员。

此模式在实现单例等设计模式时用于访问者模式和工厂模式。它还用于为维护库性能提供可扩展性。它避免使用虚函数分派来实现静态多态。

当基类希望访问和修改派生类的变量和成员函数时,主要使用此模式。例如,有一个基类模板 `vehicle` 和另一个派生类 `car`。该模板有一个 `drive` 方法,它会访问在派生类中实现的 `driveAction` 方法。在 `main` 函数中,我们为 `car` 创建一个对象,并调用 `drive` 方法。它会调用 `driveAction` 方法。通过这种方式,CRTP 允许基类在编译时访问派生类,从而实现静态多态。

使用 CRTP 的应用

CRTP 的一些应用如下:

  • 此模式用于库设计、数学和科学计算。
  • CRTP 用于开发框架和引擎,这在游戏开发中很有帮助。
  • 它们也用于嵌入式系统。
  • CRTP 经常用于模板元编程以减少运行时开销。
  • 此模式也用于代码生成任务。

示例 1

让我们来看一个实现奇异递归模板模式的 C++ 程序。

输出

Curiously Recurring Template Pattern (CRTP) in C++

说明

上述程序在 C++ 中实现了 CRTP。在此程序中,有一个名为 `shape` 的基类模板,以及两个派生类 `Circle` 和 `Rectangle`。当基类 `Shape` 尝试调用 `calculateArea()` 函数时,即使它不知道此函数在子类中的具体实现,也能成功调用。这只有通过 CRTP 才可能实现。通过将 `Circle` 作为模板参数传递,基类可以调用其子类的函数。

示例 2:使用 CRTP 实现事件处理系统

让我们举一个例子来说明在 C++ 中使用 CRTP 实现事件处理系统。

输出

Curiously Recurring Template Pattern (CRTP) in C++

说明

在上述程序中,我们使用基类模板作为 "EventHandler",派生类作为 "MouseEventHandler"。此派生类实现了 "processEvent" 函数。当我们创建派生类 "MouseEventHandler" 的对象并调用 "handleEvent" 时,它会调用 "processEvent" 函数。这是通过将 "MouseEventHandler" 作为模板参数传递给基类 "EventHandler" 来实现的。因此,基类利用此信息来调用其子类的函数。

示例 3

让我们看另一个关于奇异递归模板单例模式的 C++ 程序。

输出

Curiously Recurring Template Pattern (CRTP) in C++

说明

该程序使用 CRTP 创建一个类的单一实例。在程序的整个执行过程中,该类只有一个实例存在。在这里,"Singleton" 是基类模板,"MySingleton" 是派生类。这个派生类有一个 "doSomething" 方法。在 main() 函数中,我们使用 getInstance() 方法获取 "MySingleton" 的单一实例,并使用此实例调用 "doSomething" 方法。


下一个主题Sphenic-number-in-cpp