有趣的C++依赖注入方案
Interesting C++ dependency injection scheme
背景:我是C++的新手。我有一个C#项目,我想将其转换为C++,以便在编写一些有用的C++代码方面获得一些经验,而不仅仅是课本上的例子。为此,我检查了一些开源项目的代码,以获得真实C++的感觉,并尝试在一个相当旧的项目中进行一些重构,在调试构建中使用一些valgrind操作和一些ad-hoc统计数据来确认正确性(所有这些都有真实的输入)。(几年前,我用C++做过一个大学项目,但我不认为这是真正的经验)。
实际问题:
我试图转换为C++的C#项目使用了轻量级依赖注入。每个类都在构造函数中接收一个"上下文"对象。在查询自己的依赖关系之前,它首先将自己插入"上下文"中,这样循环依赖关系就不会成为问题。
经过一番思考,我想出了一个用C++编写的方案。每个DI对象都通过构造函数中的引用接收其依赖项。我在一个类中创建所有DI对象字段(按值作为子对象),并将它们连接到初始化列表中。
// Yes, the project is compiler for a toy programming language
class Compiler {
Logger log;
Options options;
ParserDriver parserDriver;
DeclarationAnalysis declarationAnalysis;
CodeTypeAnalysis codeTypeAnalysis;
FlowAnalysis flowAnalysis;
CodeGeneration codeGeneration;
Check check;
Typings typings;
Operators operators;
Symtab symtab;
public:
Compiler();
};
Compiler::Compiler() :
log(),
options(),
parserDriver(log),
declarationAnalysis(log, symtab, check),
codeTypeAnalysis(log, symtab, operators, typings, check),
flowAnalysis(log),
codeGeneration(typings, symtab),
check(log, symtab),
typings(symtab),
operators(symtab, log, typings),
symtab()
{}
// Example DI object
class DeclarationAnalysis {
Logger* log;
Symtab* symtab;
Check* check;
public:
DeclarationAnalysis(Logger&, Symtab&, Check&);
}
DeclarationAnalysis::DeclarationAnalysis(Logger& log, Symtab& symtab, Check& chack)
: log(&log), symtab(&symtab), check(&check) {}
这样的代码是否正确,因为它是安全的,没有未定义的行为(例如,symtab
是最后初始化的,但作为参数提供给其他字段的构造函数)?乍一看很优雅。内存是打包的,甚至可以在堆栈上分配。我是否重新发现了现有的模式?
构造函数初始化列表是按对象在类中存在的顺序调用的。如果构造函数列表的顺序不同,则可以将编译器设置为warn。打开它。
您可以获取对未初始化值的引用并将其传递。除了存储指向那些未初始化对象的指针或引用之外,任何其他操作都不是一个好计划。
在示例代码中,您只存储指针。这是安全的。
这些类型的析构函数不能假设指向的对象存在,因为在Compiler
构造的过程中,它可能会失败(通过异常),并导致已经构造的子对象的破坏。这很难纠正。
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- C++11 中不同类型的对象的 std::array 的替代方案
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 无法使用加载库卸载注入的 dll (C++)
- 将 dll 文件注入 UWP
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 模板或链接接缝依赖注入有哪些替代方案来测试非虚拟方法?
- 有趣的C++依赖注入方案