策略模式中应该使用安全指针吗?

2024-02-16

给定一个典型的策略模式

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;
}

我相信“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
}

鉴于安全指针,现在是否最好注入一个安全指针,并且有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_;
}

or if 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的可以被注入到Context.


设计取决于实施者。

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

直接回答你的问题:

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

进一步回答这个问题:

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

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

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

策略模式中应该使用安全指针吗? 的相关文章

  • asp.net 文本框文本模式数字,仅允许数字

    我只是想知道 ASP NET 中是否有一种方法只允许文本框中的数字textmode number 当我使用这个时
  • 迭代变量并查找特定类型实例的技术

    我想迭代进程中内存中的变量 通过插件动态加载 并查找特定类型的实例 以前我可以找到特定类型 或内存中的所有类型 我可以创建类型的实例 我可以获取作为不同类型的字段包含的实例 但我无论如何都不知道只是 搜索 特定类型的实例 一种方法是使用 W
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 以编程方式检查页面是否需要基于 web.config 设置进行身份验证

    我想知道是否有一种方法可以检查页面是否需要基于 web config 设置进行身份验证 基本上如果有这样的节点
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • 对齐 GridView 中的行值

    我需要在 asp net 3 5 中右对齐 gridview 列中的值 我怎样才能做到这一点
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • 当前的 c++ 工作草案与当前标准有何不同

    通过搜索该标准的 PDF 版本 我最终找到了这个链接C 标准措辞草案 http www open std org jtc1 sc22 wg21 docs papers 2012 n3376 pdf从 2011 年开始 我意识到我可以购买最终
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 结构体指针的动态数组

    我必须使用以下代码块来完成学校作业 严格不进行任何修改 typedef struct char firstName char lastName int id float mark pStudentRecord pStudentRecord
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 剪贴板在 .NET 3.5 和 4 中的行为有所不同,但为什么呢?

    我们最近将一个非常大的项目从 NET Framework 3 5 升级到 4 最初一切似乎都工作正常 但现在复制粘贴操作开始出现错误 我已经成功制作了一个小型的可复制应用程序 它显示了 NET 3 5 和 4 中的不同行为 我还找到了一种解
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐