Однажды я читал удивительный FAQ по C ++ (это действительно хорошо !! https://isocpp.org/faq) и прочитайте тему о том, как предотвратить статический порядок инициализации «фиаско». Поэтому автор советует обернуть статические переменные в функции, чтобы избежать фиаско, поддерживая порядок создания переменных. Но это кажется мне грубым обходным путем. Поэтому мой вопрос заключается в том, существует ли какой-либо современный, более ориентированный на шаблоны способ предотвращения этого «фиаско», но заключить «статический материал» в функции ???
Современный, более ориентированный на шаблоны способ не использовать глобалы в первую очередь.
Другого пути нет.
В противном случае это не будет большим фиаско!
Поэтому мой вопрос заключается в том, существует ли какой-либо современный, более ориентированный на шаблоны способ предотвращения этого «фиаско», но заключить «статический материал» в функции ???
В большинстве случаев вы можете объявить свои «глобальные» данные в основной функции и использовать внедрение зависимостей для их передачи, где это необходимо. Другими словами, не имеют статического состояния вообще.
На практике могут возникнуть ситуации, когда необходимы статические данные. Если нет никаких зависимостей от других статик, сделайте статические данные const/constexpr
,
// smart pointer that implements the "Foo" release policy
class FooPointer
{
static const FooPointer NullFoo; // does not depend on other static values
/* ... */
};
В случае статических переменных делать зависят друг от друга, просто оберните их в статические функции:
// smart pointer that implements the "Foo" release policy
class FooPointer
{
static const FooPointer& NullFoo(); // depends on other static values
/* ... */
};
Подвести итоги:
Большинство (90%? 99%?) Статических / глобальных / общих данных должны быть внедрены в зависимости от того, где они используются, а не создаваться как статические вообще.
В тех редких случаях, когда статика необходима по той или иной причине и не зависит от других статик, объявляйте статические переменные.
в очень В редких случаях, когда статика должна быть статичной и зависит друг от друга, стирайте их статическими методами.
Как правило, если у вас много второго и третьего случаев, вы недостаточно делаете первый.
Более обычный способ решения этой проблемы — избегать статики, когда это возможно, и тем более между объектами, которые зависят от порядка построения.
Затем постройте объекты в нужном порядке. Например, если у нас есть два объекта x и y, и построение y завершится неудачей, если x не было построено, то сначала создайте x и передайте его конструктору (или другому члену) y)
SomeObject x;
SomeOtherObject y(x);
или же
SomeObject *x = new SomeObject;
SomeOtherObject y = new SomeObject(*x);
(оба вышеупомянутых предполагают конструктор y
требуется ссылка).
Если вам нужно поделиться x
а также y
между функциями, просто передайте их функциям в качестве аргументов.
Если вам нужно использовать статику (то есть вы не хотите, чтобы ввод передаваемых аргументов был везде), сделайте статики указателями и инициализируйте их один раз (например, в main()
).
// all source files can use x and y via these declarations (e.g. via a header file)
extern SomeObject *x;
extern SomeOtherObject *y;
// definition in one source file only
SomeObject *x;
SomeOtherObject *y;
int main()
{
x = new SomeObject;
y = new SomeOtherObject(*x);
// call other functions that use x and y.
delete y;
delete x;
}
Но, действительно, лучше избегать использования статики, если это вообще возможно.