c++ - 应该在策略模式中使用安全指针吗?

标签 c++ c++11 design-patterns 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;
}

我相信实现上下文类的“pre-C++11”方式类似于

class ContextRaw
{
public:
    ContextRaw(Strategy* the_strategy);
    ~ContextRaw(); // Should this delete the_strategy_?
    int execute() const;
private:
    Strategy* the_strategy_;
}

对我来说,在这个设计中,不清楚 Context 是否应该为 Strategy 负责,除非有明确的文档说明,否则可能会发生不好的事情

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
}

鉴于安全指针,现在是否应该注入(inject)安全指针并让 Context 拥有 Strategy 的所有权?

class ContextUnique
{
public:
    ContextUnique() = delete;
    ContextUnique(std::unique_ptr<Strategy> the_strategy);
    ~ContextUnique();
    int execute() const;
private:
    std::unique_ptr<Strategy> the_strategy_;
}

或者 Strategy 是否可以在不同的 Context 之间共享?

class ContextShared
{
public:
    ContextShared() = delete;
    ContextShared(std::shared_ptr<Strategy> the_strategy);
    ~ContextShared();
    int execute() const;
private:
    std::shared_ptr<Strategy> the_strategy_;
}

这种设计当然会引入其自身的问题,特别是只有动态分配的 Strategy 才能注入(inject)到 Context 中。

最佳答案

设计由实现者决定。

请注意,在您的示例中,您引用了使用非 C++11 指针搞砸策略模式的不同方式。

直接回答您的问题:

是的,你应该在策略模式中使用智能指针。

进一步回答问题:

您应该尽可能使用智能指针。

原因是智能指针在内存所有权策略方面实际上是自记录的,因此您摆脱了“如果没有好的文档”的一些缺点。

考虑到您为 Context 类公开的原型(prototype),您可以告诉用户您的期望是什么:

  • unique_ptr 如果您希望用户将内存所有权传递给您
  • shared_ptr 如果您希望对多个所有者使用相同的策略实现
  • weak_ptr 如果你想让用户处理内存管理

什么更安全,由您决定。但是,您可以告诉用户上下文可以与其他上下文共享它的具体策略,或者每个上下文有 1 个具体策略。

作为一种设计方法,我建议采用 1 个 Strategy/Context(如此 unique_ptr),因为您的具体策略最终可能会有一些内部变量,这些变量是 unique/context ,并且事情会从那里变得复杂。

关于c++ - 应该在策略模式中使用安全指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28364689/

相关文章:

c++ - "State pattern"与 "one member function per state"?

c++ - 使用 lambda 从 boost::thread 检索返回值

c++ - 如何用不同类的对象填充类中的 vector

c++ - 如何制作一个函数模板,它接受一个带有可变参数的仿函数

c++ - C++ 标准是否要求对 wchar_t 进行编码?

c++ - 我的程序结构/设计所需的输入

Swing 中的 Java 创 build 计模式

c++ - 将派生类数组分配给基类指针

c++ - 从第二个线程访问主线程中的变量

c++ - 寻找模式 C++