策略模式在c++++中通过模板参数注入实现编译期解耦和性能优化。1. 核心思路是将策略作为模板参数传入上下文类,编译时确定行为,避免虚函数运行时开销;2. 策略类需统一实现相同成员函数(如apply()),以满足接口一致性;3. 使用时根据策略类型实例化context模板,提升执行效率;4. 优点包括编译期绑定、减少二进制膨胀及更高的灵活性;5. 局限在于策略须提前确定且过多会导致代码膨胀;6. 可结合std::function支持运行时切换策略,兼顾灵活性与性能。

在C++中,策略模式常用于解耦算法或行为的变化。传统做法是通过继承和虚函数实现多态,但用模板参数注入策略的方式,可以在编译期确定行为,提升性能并减少运行时开销。

基本思路:模板参数传入策略类
核心思想是将策略作为模板参数传入上下文类(Context),这样在编译时就能确定具体使用哪种策略,无需虚函数表等运行时机制。

例如:
立即学习“C++免费学习笔记(深入)”;
templateclass Context { public: void execute() { strategy_.apply(); } private: Strategy strategy_; };
每个不同的
Strategy都会实例化一个独立的
Context类型,执行效率高。

定义策略接口:统一调用方式
虽然没有显式的接口概念,但可以通过约定让各个策略类提供相同的成员函数,供
Context调用。
比如定义两个策略类:
struct StrategyA {
void apply() const { std::cout << "Using Strategy A\n"; }
};
struct StrategyB {
void apply() const { std::cout << "Using Strategy B\n"; }
};只要它们都实现了
apply()方法,就可以被统一使用。
使用方式:实例化不同模板类型
在实际使用时,只需根据需要选择不同的策略类来实例化
Context:
ContextctxA; ctxA.execute(); // 输出 "Using Strategy A" Context ctxB; ctxB.execute(); // 输出 "Using Strategy B"
这种方式避免了继承体系和虚函数的开销,适合对性能敏感的场景。
这种方式的优点包括:
- 编译期绑定,运行更快
- 避免虚函数带来的二进制膨胀
- 更加灵活,策略可以是任何满足接口要求的类
但也有一些限制需要注意:
- 策略必须在编译期确定
- 每个策略都会生成一份新的模板实例代码
- 不适合策略种类非常多、体积很大的情况
扩展思路:结合std::function实现运行时策略切换
如果你希望同时支持编译期和运行时策略切换,也可以混合使用模板与
std::function:
class DynamicContext {
public:
template
void set_strategy(Strategy&& strategy) {
strategy_ = std::forward(strategy);
}
void execute() const {
if (strategy_) strategy_();
}
private:
std::function strategy_;
}; 这样既能使用模板设置策略,又能保持一定的灵活性。
基本上就这些。这种基于模板的策略注入方式,在编写高性能库或底层组件时非常实用,值得掌握。










