Глобалы не злые
Надо было сначала снять это с моей груди:)
Я бы вставил константы в структуру и сделал бы глобальный экземпляр этого:
struct Constants
{
double g;
// ...
};
extern Constants C = { ... };
double Grav(double m1, double m2, double r) { return C.g * m1 * m2 / (r*r); }
(короткие имена тоже в порядке, все ученые и инженеры так делают .....)
Я использовал тот факт, что локальные переменные (то есть члены, параметры, локальные функции и т. Д.) В некоторых случаях имеют приоритет над глобальными в качестве «аспектов для бедных»:
Вы можете легко изменить метод на
double Grav(double m1, double m2, double r, Constants const & C = ::C)
{ return C.g * m1 * m2 / (r*r); } // same code!
Вы можете создать
struct AlternateUniverse
{
Constants C;
AlternateUniverse()
{
PostulateWildly(C); // initialize C to better values
double Grav(double m1, double m2, double r) { /* same code! */ }
}
}
Идея состоит в том, чтобы написать код с наименьшими издержками в случае по умолчанию и сохранить реализацию, даже если универсальные константы должны измениться.
Вызов сфера против области источника
В качестве альтернативы, если вы / ваши разработчики более склонны к процедурному, а не к стилю ОО, вы можете использовать область вызова вместо исходная область с глобальным стеком значений, примерно
std::deque<Constants> g_constants;
void InAnAlternateUniverse()
{
PostulateWildly(C); //
g_constants.push_front(C);
CalculateCoreTemp();
g_constants.pop_front();
}
void CalculateCoreTemp()
{
Constants const & C= g_constants.front();
// ...
}
Все в дереве вызовов использует "самые актуальные" константы. OYu может вызывать одно и то же дерево процедур - независимо от того, насколько глубоко оно вложено - с альтернативным набором констант. Конечно, он должен быть лучше инкапсулирован, безопасен для исключений, а для многопоточности вам нужно локальное хранилище потоков (чтобы каждый поток получал свой собственный «стек»)
Расчет против пользовательского интерфейса
Мы по-разному подходим к вашей исходной проблеме: все внутреннее представление, все постоянные данные используют базовые единицы СИ. Преобразование происходит на входе и выходе (например, несмотря на то, что типичный размер равен миллиметру, он всегда хранится как метр).
Я не могу сравнивать, но у нас это хорошо работает.
Анализ размеров
Другие ответы как минимум намекают на анализ измерений, например, Boost Library . Он может обеспечить корректность размеров и автоматизировать преобразования ввода / вывода.