C++ 模板专题 - 静态多态(CRTP)

一:概述:

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;
}
相关推荐
蜗牛一步步往上爬1 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y3 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
wo_jack5 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH5 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶6 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing036 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊6 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
波力海苔夹心脆6757 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
不会算法的笨小孩8 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
Hhy_110710 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio