有趣的C++;依赖注入方案 背景:我是C++初学者。我有一个C项目,我想转换成C++,以获得一些有用的C++编写代码的经验,超越教科书的例子。为此,我研究了一些开源项目的代码,以获得真实C++的感觉,并且尝试在一个相当旧的项目中进行一些重构,其中一些ValgRAND动作和一些调试中的临时统计来确认正确性(所有都是真实输入)。(我在几年前做了一个C++项目,但我不认为这是任何真实的经验)。

有趣的C++;依赖注入方案 背景:我是C++初学者。我有一个C项目,我想转换成C++,以获得一些有用的C++编写代码的经验,超越教科书的例子。为此,我研究了一些开源项目的代码,以获得真实C++的感觉,并且尝试在一个相当旧的项目中进行一些重构,其中一些ValgRAND动作和一些调试中的临时统计来确认正确性(所有都是真实输入)。(我在几年前做了一个C++项目,但我不认为这是任何真实的经验)。,c++,dependency-injection,C++,Dependency Injection,实际问题: 我试图转换为C++的C项目使用Lite权重依赖注入。每个类在构造函数中接收一个“上下文”对象。它首先将自己插入“上下文”,然后再查询自己的依赖项,这样循环依赖项就不会成为问题 经过思考,我在C++中提出了一个后续的方案。每个DI对象都通过构造函数中的引用接收其依赖项。我在一个类中创建所有DI对象字段(按值作为子对象),并将它们连接到初始化列表中 //是的,该项目是一种玩具编程语言的编译器 类编译器{ 测井日志; 选项; ParserDriver ParserDriver; 声明分析声

实际问题:

我试图转换为C++的C项目使用Lite权重依赖注入。每个类在构造函数中接收一个“上下文”对象。它首先将自己插入“上下文”,然后再查询自己的依赖项,这样循环依赖项就不会成为问题

经过思考,我在C++中提出了一个后续的方案。每个DI对象都通过构造函数中的引用接收其依赖项。我在一个类中创建所有DI对象字段(按值作为子对象),并将它们连接到初始化列表中

//是的,该项目是一种玩具编程语言的编译器
类编译器{
测井日志;
选项;
ParserDriver ParserDriver;
声明分析声明分析;
代码类型分析代码类型分析;
流动分析;
代码生成代码生成;
检查检查;
打字;
经营者;
Symtab Symtab;
公众:
编译器();
};
编译器::编译器():
log(),
选项(),
帕塞德河(原木),
声明分析(日志、符号表、检查),
代码类型分析(日志、符号表、运算符、键入、检查),
流量分析(日志),
代码生成(打字、符号表),
检查(日志,符号表),
打字(符号表),
操作员(符号表、日志、打字),
symtab()
{}
//示例DI对象
类声明分析{
记录器*日志;
Symtab*Symtab;
检查*检查;
公众:
声明分析(Logger&,Symtab&,Check&);
}
DeclarationAnalysis::DeclarationAnalysis(记录器和日志、符号选项卡和符号选项卡、检查和检查)
:log(&log)、symtab(&symtab)、check(&check){}

这样的代码是安全的,没有未定义的行为(例如,
symtab
最后初始化,但作为参数提供给其他字段的构造函数)吗?乍一看似乎很优雅。内存是打包的,甚至可以在堆栈上分配。我是否重新发现了现有模式?

构造函数初始化列表被调用,以便对象在类中存在。编译器可以设置为警告。如果构造函数列表的顺序不同。把它打开

您可以引用未初始化的值并传递它们。除了存储指向那些未初始化对象的指针或引用之外,任何其他东西都不是一个好计划

在示例代码中,您只存储指针。那是安全的


这些类型的析构函数不能假定指向的对象存在,在编译过程中,它可能会失败(通过异常)并导致已构造的子对象的破坏。这很难做到正确。

如果您要求改进和审查已经在运行的代码,您应该参考。对于堆栈溢出,您的问题看起来很广泛。从:“非静态数据成员按类定义中的声明顺序初始化”——因此,使用<代码> SimultAs/Cuth>不安全。您可能对C++中的依赖性注入框架感兴趣。例如,如果我对init列表重新排序,使所有字段在作为参数提供给其他构造函数之前都已初始化,那么即使我使用所述构造函数中的对象也是安全的?@irpbc构造函数的顺序。类中的irder是否不在构造时的列表中;对不起,我不清楚。哦。。。好的,我现在知道了:),顺序是在类主体中声明的顺序。这就解决了问题。