问题描述
给定一个典型的策略模式
类策略
{
public:
virtual int execute()const = 0;
}
class StrategyA:public Strategy
{
public:
int execute()const override;
}
class StrategyB:public Strategy
{
public:
int execute()const override;
}
我相信前C ++ 11类将是类似
类ContextRaw
{
public:
ContextRaw the_strategy);
〜ContextRaw(); //这应该删除the_strategy_吗?
int execute()const;
private:
Strategy * the_strategy_;
}
对我来说,在这个设计中不清楚上下文
应该负责 Strategy
,除非有明确的文件说明,否则可能会发生不好的事情
void trouble()
{
StrategyA a_concrete_strategy;
ContextRaw a_context(& a_concrete_strategy); //哎,上下文可能会尝试删除栈变量
}
void more_trouble()
{
策略* a_concrete_strategy = new StrategyA;
ContextRaw * a_context = new ContextRaw(a_concrete_strategy);
ContextRaw * another_context = new ContextRaw(a_concrete_strategy);
delete a_context;
std :: cout<< another_context.execute()<< std :: endl; // Oops,the_strategy is deleted
}
鉴于安全指针,现在最好注入一个安全的指针,并且 Context
取得 Strategy
?
$ b
class ContextUnique
{
public:
ContextUnique()= delete;
ContextUnique(std :: unique_ptr< Strategy> the_strategy);
〜ContextUnique();
int execute()const;
private:
std :: unique_ptr< Strategy> the_strategy_;
}
可以在不同的上下文
之间共享
class ContextShared
{
public:
ContextShared()= delete;
ContextShared(std :: shared_ptr< Strategy> the_strategy);
〜ContextShared();
int execute()const;
private:
std :: shared_ptr< Strategy> the_strategy_;
}
此设计当然会引入自己的问题, code> Strategy 可以注入上下文
。
根据 std :: function $ c $
std :: function< int()>
和一些lambdas。 Given a typical strategy pattern
class Strategy
{
public:
virtual int execute() const = 0;
}
class StrategyA : public Strategy
{
public:
int execute() const override;
}
class StrategyB : public Strategy
{
public:
int execute() const override;
}
I believe the 'pre-C++11' way to implement a context class would be something like
class ContextRaw
{
public:
ContextRaw(Strategy* the_strategy);
~ContextRaw(); // Should this delete the_strategy_?
int execute() const;
private:
Strategy* the_strategy_;
}
To me, in this design it's not clear if Context
should take responsibility for Strategy
, and unless there is clear documentation stating otherwise, bad things might happen if it does
void trouble()
{
StrategyA a_concrete_strategy;
ContextRaw a_context(&a_concrete_strategy); // Oops, Context may try to delete stack variable
}
void more_trouble()
{
Strategy* a_concrete_strategy = new StrategyA;
ContextRaw* a_context = new ContextRaw(a_concrete_strategy);
ContextRaw* another_context = new ContextRaw(a_concrete_strategy);
delete a_context;
std::cout << another_context.execute() << std::endl; // Oops, the_strategy is deleted
}
In light of safe-pointers, should it now be preferable to inject a safe pointer, and have Context
take ownership of the Strategy
?
class ContextUnique
{
public:
ContextUnique() = delete;
ContextUnique(std::unique_ptr<Strategy> the_strategy);
~ContextUnique();
int execute() const;
private:
std::unique_ptr<Strategy> the_strategy_;
}
or if Strategy
can be shared amongst different Context
?
class ContextShared
{
public:
ContextShared() = delete;
ContextShared(std::shared_ptr<Strategy> the_strategy);
~ContextShared();
int execute() const;
private:
std::shared_ptr<Strategy> the_strategy_;
}
This design of course introduces problems of it's own, in particular only dynamically allocated Strategy
's can be injected into Context
.
You're doing it wrong.
In the light of std::function
, everything you've just written is completely obsolete and you should just use std::function<int()>
and some lambdas.
这篇关于应该在策略模式中使用安全指针吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!