c++:没有全局变量或单例或将其传递给每个方法的记录器类

标签 c++ logging dependency-injection singleton

有谁知道是否有可能有一个像记录器这样的类而没有:

  • 使用单例或全局(例如 std::cout)

  • 将实例/指针/引用传递给每个需要它的方法

我以记录器类为例,但我的应用程序中有一些类可以从中受益(例如,撤消管理器)。

每个解决方案都有几个问题:

  • 使用单例对测试来说是有问题的(以及许多原因,使用单例通常不是一个好主意)。全局也是一样。此外,没有什么能保证应用程序中只有一个实例,甚至不是必需的(例如,为什么没有 2 个记录器?)

  • 将它传递给每个对象构造函数(依赖注入(inject)),会导致大量样板代码,并且可能容易出错,因为您必须多次复制/粘贴相同的代码。可以认真考虑在每个类的构造函数中都有一个指向 Logger 的指针吗??????

所以我想知道是否有第三种替代方案,在 C++ 中,我从未听说过? 对我来说,这听起来像是需要一些黑魔法,但我对我在堆栈溢出中学到的一些我在谷歌找不到的技术感到惊喜,所以我知道这里有一些真正的大师;)

令人惊讶的是,我发现很多关于如何设计单例或为什么不应该使用单例的讨论,但我找不到解决我的问题的帖子...

最佳答案

我想你可以用 Log4j 包做类似于 Java 中所做的事情(并且可能用它的 Log4c 版本完成):

有一个可以返回多个记录器实例的静态方法:

Logger someLogger = Logger.getLogger("logger.name");

getLogger() 方法没有返回单例对象。它返回命名的记录器(如有必要,创建它)。 Logger 只是一个接口(interface)(在 C++ 中它可能是一个完全抽象的类)——调用者不需要知道正在创建的 Logger 对象的实际类型。

你可以继续模仿 Log4j 并有一个 getLogger() 的重载,它也需要一个工厂对象:

Logger someLogger = Logger.getLogger("logger.name", factory);

该调用将使用 factory 来构建记录器实例,让您可以更好地控制正在创建的底层 Logger 对象,这可能有助于您的模拟。

因此,无需将任何内容传递给您自己代码的构造函数、方法等。您只需在需要时获取所需的名为 Logger 并登录到它。根据您编写的日志记录代码的线程安全性,您可以将 getLogger() 返回的内容作为类的静态成员,因此您只需调用 getLogger() 每堂课一次。

关于c++:没有全局变量或单例或将其传递给每个方法的记录器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5877779/

相关文章:

c++ - 破译损坏的 C++ 名称 $$F

scala - logback 中的过滤标记

asp.net-mvc - 我应该如何对从 Controller 发送电子邮件进行单元测试?

具有共享首选项的 Flutter 依赖注入(inject)

java - 如何在每次方法执行时创建(和写入)新的日志文件?

php - 通过依赖注入(inject)传递静态类

c++ - 函数重载,无法推导出模板参数

c++ - 无法使用编译器将我的 C++ 文件放入库中

c++ - 如何在 OpenCV 中使用相机

java - 在 Apache 服务器中维护日志文件