一:概述:
CRTP(Curiously Recurring Template Pattern)是一种常用的 C++ 模式,用于实现静态多态性。通过 CRTP,可以在编译期确定子类类型,从而避免动态多态性带来的运行时开销。这种模式主要通过让基类接受派生类作为模板参数来实现。
二:基本用法:
cpp
#include <iostream>
template <typename Derived>
/*
Base 类接受一个模板参数 Derived,并通过 static_cast<Derived*>(this)->implementation()
调用派生类的实现。
*/
class Base {
public:
void interface() {
// 基类实现了部分逻辑,并依赖于 Derived 类来完成特定逻辑
static_cast<Derived*>(this)->implementation();
}
// 可以提供一个通用的默认实现
void implementation() {
std::cout << "Default implementation in Base\n";
}
};
/*
Derived 继承自 Base<Derived> 并提供了 implementation() 的自定义实现。
*/
class Derived : public Base<Derived> {
public:
// 派生类提供特定的实现
void implementation() {
std::cout << "Custom implementation in Derived\n";
}
};
int main() {
/*
Base 中的 interface() 方法通过 CRTP 调用派生类的 implementation(),实现了类似虚函数
的效果,但不需要运行时的动态分派。
*/
Derived d;
d.interface(); // 输出 Custom implementation in Derived
return 0;
}
三: 应用示例(编译期策略模式)
cpp
#include <iostream>
// 策略接口类:定义计算价格的接口
template <typename Derived>
class DiscountStrategy {
public:
double applyDiscount(double price) const {
// 调用具体策略类实现的算法
return static_cast<const Derived*>(this)->applyDiscount(price);
}
};
// 无折扣策略
class NoDiscount : public DiscountStrategy<NoDiscount> {
public:
double applyDiscount(double price) const {
return price;
}
};
// 百分比折扣策略
class PercentageDiscount : public DiscountStrategy<PercentageDiscount> {
public:
PercentageDiscount(double percentage) : discountPercentage(percentage) {}
double applyDiscount(double price) const {
return price * (1 - discountPercentage / 100.0);
}
private:
double discountPercentage;
};
// 购买商品类,采用编译期策略模式
template <typename Strategy>
class Product {
public:
Product(double basePrice, Strategy discountStrategy)
: price(basePrice), strategy(discountStrategy) {}
double getPrice() const {
return strategy.applyDiscount(price);
}
private:
double price;
Strategy strategy;
};
int main() {
// 使用无折扣策略
Product<NoDiscount> item1(100.0, NoDiscount());
std::cout << "Price with no discount: " << item1.getPrice() << std::endl;
// 使用百分比折扣策略
Product<PercentageDiscount> item2(100.0, PercentageDiscount(10.0)); // 10% 折扣
std::cout << "Price with 10% discount: " << item2.getPrice() << std::endl;
return 0;
}