Это основной вопрос о том, какие параметры доступны для определения области действия некоторых параметров.Мне бы особенно хотелось ощутить компромисс в скорости, памяти, четкости кода, простоте реализации и безопасности кода.Мой опыт программирования явно скромный, и у меня мало формального обучения.Я подозреваю, что один или два варианта будут очевидными «правильными» ответами.
У меня есть симуляция, инкапсулированная в свой собственный класс под названием Simulation
.Некоторые параметры, используемые в симуляции, считываются из набора файлов при инициализации симуляции, и эти параметры в настоящее время хранятся в нескольких двумерных массивах.Эти массивы demPMFs
и serotypePars
в настоящее время являются частными членами Simulation
:
// Simulation.h
class Simulation
{
Simulation( int simID );
~Simulation();
public:
// ...[code snipped]...
private:
double demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ];
double serotypePars[ NUM_EPID_FILES ][ INIT_NUM_STYPES ];
// ...[code snipped]...
};
Моделирование в основном включает изменение экземпляров класса Host
.Функции-члены класса Host
часто нуждаются в доступе к значениям параметров, хранящимся в serotypePars
.Раньше у меня были все данные в serotypePars
, хранящиеся в виде чисел const
, интерпретируемых во время компиляции, но теперь, когда эти параметры читаются из файла, все немного сложнее (для меня, во всяком случае).
Какой самый быстрый и безопасный способ предоставить всем членам класса Host
доступ «только для чтения» к serotypePars
? Самый быстрый заслуживает приоритета: в моей программе нет других классовпоэтому global
является (сырым) потенциальным решением;Все симуляции будут выполняться с одинаковыми наборами параметров.Я неохотно передаю массив отдельным функциям, которые действуют на Host
членов, так как их, вероятно, дюжина, а некоторые довольно вложенные.(Например, у меня есть промежуточные структуры-обертки, которые не могут принимать двумерные массивы в качестве аргументов, и я не уверен, какие могут быть синтаксические обходные пути. Я хотел бы использовать массивы для целей скорости и мой неоднородный prngвсе генераторы ожидают массивы.)
Я был бы очень признателен, зная, что потребовало бы наименьшего изменения существующего кода, не создавая при этом больших опасностей.
Спасибо за любую информацию, которую вы можете предложить.
У меня есть проблема, связанная с тем, что я не знаю точно, как получить доступ к членам Simulation из класса Host, если только эти участники не переданы в Hostфункция.Вот в основном то, что происходит:
// main.cpp
int main() {
for ( int s = 1; s < NUM_SIMS+1; s++ ) {
Simulation thisSim(s);
thisSim.runDemSim();
thisSim.runEpidSim();
// ... code snipped ...
}
}
Функция Simulation::runDemSim()
и Simulation::runEpidSim()
создают, изменяют и уничтожают множество экземпляров класса Host
.Указатели на эти экземпляры хранятся в контейнере Boost MultiIndex, в который входят промежуточные функции-оболочки. Одна из многих модификаций заключается в конечном счете в вызове Host::calcRecovery
, который требует доступа к serotypePars
:
// Host.cpp
// ... code snipped ...
double Host::calcRecovery( int s, double currentTime, double infectionTime, boost::mt19937& rng ) {
// ...code snipped...
effectiveMean = serotypePars[ MEAN_DURATION_INDEX ][ s ] * currentInfections * pastInfections;
double rt = rgamma( effectiveMean, serotypePars[ VAR_DURATION_INDEX ][ s ], rng );
}
(Извиняюсь, если TMI.) Простое объявление serotypePars
public в определении класса Simulation
привело к ошибке «serotypePars не был объявлен в этой области» в Host.cpp.
Краткое изложение решения
Предложение GMan о том, чтобы я упаковал все параметры моделирования в закрытом классе, например, SimulationPars
, представляется наиболее элегантным и расширяемым маршрутом.Экземпляр SimulationPars
может принадлежать каждому Simulation
, и указатель на SimulationPars
может быть передан конструктору каждого Host
в пределах данного Simulation
.Спасибо всем за вдумчивые обсуждения.