Это Статическая инициализация Fiasco .
Согласно стандарту C ++ порядок инициализации объектов со статической продолжительностью хранения не указан, если они объявлены в разных единицах перевода .
Следовательно, любой код, основанный на порядке инициализации таких объектов, неизбежно завершится сбоем, и эта проблема известна как Статическая инициализация Fiasco в C ++.
Ваш код основан на условии, что инициализация B::str
и C::str
происходит до D::str
, что не гарантируется Стандартом.Поскольку эти 3 статических объекта продолжительности хранения находятся в разных единицах перевода, они могут быть инициализированы в любом порядке.
Как этого избежать?
решение состоит в том, чтобы использовать Построить при первом использовании идиому , короче говоря, это означает замену глобального объекта глобальной функцией, которая возвращает объект по ссылке.Объект, возвращаемый по ссылке, должен иметь вид local static . Поскольку статические локальные объекты создаются при первом прохождении контроля над их объявлением, объект будет создан только при первом вызове, и при каждом последующем вызове тот же объект будетбыть возвращен, таким образом имитируя поведение, которое вам нужно.
Это должно быть Интересное прочтение:
Как предотвратить «фиаско статического порядка инициализации»?