Справочная информация: Я новичок в C ++.У меня есть проект на C #, который я хочу преобразовать в C ++, чтобы получить некоторый опыт написания полезного кода на C ++, помимо примеров из учебников.С этой целью я изучил код некоторых проектов с открытым исходным кодом, чтобы почувствовать настоящий C ++, а также попытался провести некоторый рефакторинг в довольно старом проекте с некоторым действием valgrind и некоторой статистикой adhoc в отладочной сборке, чтобы подтвердить правильность (всес реальным вкладом).(Я делал проект колледжа на C ++ несколько лет назад, но я не считаю это реальным опытом).
Актуальный вопрос:
Проект C #, который я пытаюсь преобразовать в C ++, использует инъекцию облегченной зависимости от веса.Каждый класс получает объект «context» в конструкторе.Сначала он вставляется в «контекст», а затем запрашивает свои собственные зависимости, чтобы циклические зависимости не были проблемой.
После некоторых размышлений я придумал следующую схему в 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
инициализируется последним, но передается в качестве аргумента конструкторам других полей)?Это кажется очень элегантным с первого взгляда.Память упакована, даже может быть выделена в стеке.Я заново открыл существующий шаблон?