C++ 为什么有人会喜欢静态策略而不是动态策略? #包括 阶级策略 { 公众: 虚空执行()=0; }; 课堂策略1:公共策略 { 公众: virtualvoid execute()覆盖{std::cout
静态版本严格来说更强大,在某些方面更易于使用 静态版本只要求C++ 为什么有人会喜欢静态策略而不是动态策略? #包括 阶级策略 { 公众: 虚空执行()=0; }; 课堂策略1:公共策略 { 公众: virtualvoid execute()覆盖{std::cout,c++,design-patterns,strategy-pattern,C++,Design Patterns,Strategy Pattern,静态版本严格来说更强大,在某些方面更易于使用 静态版本只要求S具有成员函数execute,而动态版本要求用户继承策略 静态版本对分配策略或生存期没有要求,而在代码段中,动态版本需要堆分配。如果动态版本没有所有权,则可以选择不分配,在这种情况下,客户端必须关注策略生存期 给定静态版本,希望进行堆分配的客户端可以删除策略类型以使用单个策略类型进行堆分配。但给定上述动态版本,客户端无法撤消堆分配的要求 静态版本对编译器是完全可见的,并且此信息可用于优化。动态版本通过策略基类间接进行,因此除非编译器能够
S
具有成员函数execute
,而动态版本要求用户继承策略
静态版本对分配策略或生存期没有要求,而在代码段中,动态版本需要堆分配。如果动态版本没有所有权,则可以选择不分配,在这种情况下,客户端必须关注策略
生存期
给定静态版本,希望进行堆分配的客户端可以删除策略类型以使用单个策略类型进行堆分配。但给定上述动态版本,客户端无法撤消堆分配的要求
静态版本对编译器是完全可见的,并且此信息可用于优化。动态版本通过策略
基类间接进行,因此除非编译器能够证明(或推测),否则无法进行内联正在使用的具体策略
类。静态策略更易于使用,并且不易出错,不太可能泄漏内存,不太可能违反等。但是,同时,您的示例将静态数据放在调用堆栈的自动内存中,这与dynam相比是一个非常有限的资源ic内存。静态内存适用于具有execute
功能的每种类型,动态内存要求从strategy
派生策略。从性能角度来看,静态内存的运行时开销较小(但可能会膨胀代码)。动态内存应该是动态分派(虚拟方法)。两个版本都可以使用堆栈或堆分配(即使堆分配对于静态版本来说很奇怪)。您打算如何在动态版本中使用堆栈分配?我想ref/ptr和DynamicStrategy不接受所有权。这就剩下了生存期问题。我可能可以找到一种更好的方法。strategy1s1{};DynamicStrategy DynamicStrategy(&s1)
使用Q中的代码,这就是UB。您必须使DynamicStrategy不接受所有权。然后客户必须担心生命周期。
#include <iostream>
class Strategy
{
public:
virtual void execute() = 0;
};
class Strategy1 : public Strategy
{
public:
virtual void execute() override { std::cout << "executed1\n"; }
};
class Strategy2 : public Strategy
{
public:
virtual void execute() override { std::cout << "executed2\n"; }
};
template <typename S>
class StaticStrategy
{
S strategy;
public:
void execute()
{
strategy.execute();
}
};
class DynamicStrategy
{
Strategy* strategy;
public:
DynamicStrategy(Strategy* strategy) : strategy(strategy) {}
void execute()
{
strategy->execute();
}
void setStrategy(Strategy* newStrategy)
{
delete strategy;
strategy = newStrategy;
}
~DynamicStrategy()
{
delete strategy;
}
};
int main()
{
StaticStrategy<Strategy1> staticStrategy;
staticStrategy.execute();
DynamicStrategy dynamicStrategy(new Strategy1{});
dynamicStrategy.execute();
dynamicStrategy.setStrategy(new Strategy2{});
dynamicStrategy.execute();
}