堆栈分配的 RAII 对象与 DI 原理

2024-02-09

在 C++ 中,我经常使用 RAII 风格的对象来使代码更可靠,并将它们分配在堆栈上以使代码更具性能(并避免 bad_alloc)。

但是在堆栈上创建具体类的对象违反了依赖倒置(DI)原则并阻止了模拟该对象。

考虑以下代码:

struct IInputStream
{
    virtual vector<BYTE> read(size_t n) = 0;
};

class Connection : public IInputStream
{
public:
    Connection(string address);
    virtual vector<BYTE> read(size_t n) override;
};

struct IBar
{
    virtual void process(IInputStream& stream) = 0;
};

void Some::foo(string address, IBar& bar)
{
    onBeforeConnectionCreated();
    {
        Connection conn(address);
        onConnectionCreated();
        bar.process(conn);
    }
    onConnectionClosed();
}

我可以测试IBar::process,但我也想测试一下Some::foo,无需创建真正的 Connection 对象。

当然,我可以使用工厂,但它会使代码显着复杂化并引入堆分配。
另外,我不喜欢添加Connection::open方法,我更喜欢构造完全初始化且功能齐全的对象。

我会让Connection输入模板参数Some(或为foo如果将其提取为自由函数),但我不确定这是正确的方法(模板对很多人来说看起来像黑魔法,所以我更喜欢使用动态多态性)


您现在正在做的是“强制耦合”RAII 类和服务提供者类(如果您想要可测试性,它实际上应该是一个接口)。通过以下方式解决此问题:

  1. 抽象化Connection into IConnection
  2. 有一个单独的ScopedConnection除此之外还提供 RAII 的类

例如:

void Some::foo(string address, IBar& bar)
{
    onBeforeConnectionCreated();
    {
        ScopedConnection conn(this->pFactory->getConnection());
        onConnectionCreated();
        bar.process(conn);
    }
    onConnectionClosed();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆栈分配的 RAII 对象与 DI 原理 的相关文章

  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 如何断言 Unittest 上的可迭代对象不为空?

    向服务提交查询后 我会收到一本字典或一个列表 我想确保它不为空 我使用Python 2 7 我很惊讶没有任何assertEmpty方法为unittest TestCase类实例 现有的替代方案看起来并不正确 self assertTrue
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke

随机推荐

  • 转换 data.table 中的*一些*列类

    我想将 data table 列的子集转换为新类 这里有一个热门问题 转换 data table 中的列类 https stackoverflow com questions 7813578 convert column classes i
  • 如何将 asyncio 与其他操作系统线程同步?

    我有一个带有一个主线程的程序 我在其中生成第二个使用 asyncio 的线程 是否提供任何工具来同步这两个线程 如果一切都是异步的 我可以使用它的同步原语来完成 例如 import asyncio async def taskA lst e
  • VB.NET - 将 WinForm 应用程序导出/转换为 Web ASP.NET 应用程序的最简单方法

    背景 我有一个用 VB NET 编写的 winform 应用程序 它使用 WebService 根据用户选择进行不同采访的营销公司向用户发送不同的邀请 winform 应用程序从各种文本框 列表框和下拉列表中提取字符串值 以创建一些 XML
  • 在 Rails 应用程序中连接到 Google Analytics API [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有一个很好的教程 如何在 Rails 应用程序中与 Google Analytics API 交互
  • 将任何base64文件转换为文件并移动到php / Symfony 4中的目标路径

    预先感谢我正在创建 APIsymfony 4只是上传base64 image或通过任何文件POSTMAN我必须将文件移动到目标目录 我在控制器中编写了以下代码 通过控制器我试图将文件移动到目录 但是 我收到的错误如下 未捕获的警告 file
  • 如何阻止 IE7 由于 hasLayout 清除浮动

    我有一个包含元素 其中包含许多浮动元素 该包含元素还应用了百分比宽度值 在 IE7 中 包含浮动的元素后面的内容被清除 因为宽度值赋予了它 hasLayout 我认为 我不希望包含元素具有布局 但我确实需要它具有明确的宽度 有没有办法在 I
  • 在 bitbucket ssh 连接期间,Linux 终端上出现“错误的配置选项”。

    我想开始使用 bitbucket 我已经按照教程的步骤连接到他们的服务器 link https confluence atlassian com pages viewpage action pageId 270827678 配置文件总是有问
  • Sparklyr - 更改 Spark 中的日期格式

    我有一个 Spark 数据框 其中有一列characters作为 20 01 2000 日 月 年 但我试图将其更改为日期格式 这样我就可以使用这里的功能 https cwiki apache org confluence display
  • 计算两个列表中匹配元素的数量

    我有 2 个包含随机数量元素的列表 例如 A 1 2 4 5 和 B 1 2 3 结果应该是2 我尝试过的代码 domains Numbers1 integer Numbers2 integer int list integer predi
  • 在C中存储对lua函数的引用

    我有一个用 C 实现的基本事件处理程序 我的应用程序中还有一个嵌入式 Lua 解释器 我需要它与事件管理器交互 最终目标是能够拥有一个事件处理程序 在事件触发时同时执行 C 和 Lua 函数 我的问题是我无法想出一种简单的方法来存储对 C
  • 当命名空间应该被继承时,为什么 cxf 对没有命名空间前缀的元素抛出解组错误

    我正在创建一个在 Java 11 Spring Boot 服务器中运行并向 Java 8 服务器发出请求的 SOAP 客户端 我在 Gradle 6 9 版本中使用 cxf rt frontend jaxws 3 4 3 和 cxf rt
  • 如何通知Android Widget重画

    我有一个 Android Widget 使用RemoteViewsFactory为了填充ListView 我的数据源是一个异步 JSON 调用 可以随时完成 它不是推送通知 现在代码位于onDataChanged看起来像这样 Overrid
  • 在 MVC 操作中隐藏查询字符串

    我想将查询字符串隐藏到我的控制器的操作中 在我的应用场景中是这样的 1 我已在新窗口中打开新操作 var check Particular String var url rootUrl Home Preview Docs check win
  • 是否可以通过 flutter app 分享您的位置

    我在 flutter dart 中构建了一个应用程序来访问用户的位置 我现在想通过 Whatsapp 电子邮件等共享用户当前的物理位置 但不是作为坐标 我尝试过地理定位和位置 但似乎只能获取坐标 下面是我的分享按钮的片段 其中显示了坐标 分
  • cls() 函数在类方法中做什么?

    今天查看别人的代码 看到了这样的内容 class A B Omitted bulk of irrelevant code in the class def init self uid None self uid str uid classm
  • 过载解析异常

    不确定这是否是 C 4 特定的 但只是注意到了这一点 考虑以下类 class Base protected void Foo object bar DayOfWeek day class Program Base protected voi
  • PDO 相当于 mysql_fetch_array

    我正在努力处理相当于以下查询的 PDO 该查询计算队列中有多少个新项目 并计算出完成它们需要多少周 从而给我一个工作堆栈时间表 count new to be made new SELECT FLOOR SUM TotalNew 7 AS
  • Unity 容器 - 延迟注入

    假设我有课 class Foo FooBase public Foo Settings settings IDbRepository db base settings this db db 基本上 FooBase 通过构造函数接收设置并从配
  • java.lang.ClassCastException:[Ljava.lang.Object;无法转换或 BeanUtils.copyProperties 不起作用

    我是 JPA 新手 并且 Spring Boot 在使用 Query param 时无法获取 api 响应 我尝试实现内部联接 存储库类 Transactional rollbackFor Exception class Modifying
  • 堆栈分配的 RAII 对象与 DI 原理

    在 C 中 我经常使用 RAII 风格的对象来使代码更可靠 并将它们分配在堆栈上以使代码更具性能 并避免 bad alloc 但是在堆栈上创建具体类的对象违反了依赖倒置 DI 原则并阻止了模拟该对象 考虑以下代码 struct IInput