Гарантируется ли, что область действия Object::number переживет область действия любого созданного экземпляра Object? даже если он объявлен глобально в другом исходном файле?
Связь статики класса и нестатических экземпляров преднамеренна и различна. Object::number будет существовать даже тогда, когда никаких экземпляров Object не существует, не говоря уже о том, что они переживут любой конкретный экземпляр Object. Есть только один (если это не шаблон, но технически это не тот же класс, так как это будет сгенерированный вывод). WhozCraig 01.03.2013
Кстати, то, о чем вы спрашиваете, называется сроком службы, а не областью действия. Область видимости - это часть исходного файла, в которой видно имя. Время жизни - это период во время выполнения, когда объект существует. Steve Jessop 01.03.2013
@WhozCraig: С другой стороны, я считаю, что можно создать и использовать экземпляр Object до того, как Object::number будет инициализирован... Mooing Duck 01.03.2013
@MooingDuck - я думаю, это отвечает на точный вопрос ОП. Robᵩ 01.03.2013
@MooingDuck Мне пришлось бы серьезно погрузиться в время жизни объектов, глобальные инициализации и определения их формата в стандарте, прежде чем я смог бы подтвердить или опровергнуть, что это возможно, но меня ничуть не удивило бы, если бы это было так. Глобальная инициализация для меня всегда ненадежная вещь, поэтому я стараюсь ее избегать. WhozCraig 01.03.2013
#include <iostream>
#define X() (std::cout << __PRETTY_FUNCTION__ << "\n")
struct M {
M() { X(); }
~M() { X(); }
};
struct C {
C() { X(); }
~C() { X(); }
static M m;
};
C c;
M C::m;
int main () { X(); }
В этой программе c должен быть инициализирован до C::m и должен быть удален после C::m. Если вы скомпилируете эту программу и рассмотрите ее вывод, вы увидите что-то вроде:
C::C()
M::M()
int main()
M::~M()
C::~C()
Итак, нет, в целом, "[срок жизни] [члена]" не "гарантированно превосходит [срок службы] любого созданного экземпляра объекта?"
Ответ 2 · рейтинг 5 · Mats Petersson
Да, он имеет "статическую продолжительность хранения", что означает, что он существует "все время" [если у него есть нестандартный конструктор, конструктор вызывается перед запуском "основного" - этого должно быть достаточно для большинства намерений и целей]
Ответ 3 · рейтинг 4 · Steve Jessop
Вроде того, но только потому, что int - особый случай. Например, предположим, что вы пишете в Object.cpp:
Object o = {};
int Object::number = 5;
Тогда объект o имеет статическую продолжительность хранения, как и Object::number. Номинально он создается до number и будет уничтожен позже, но, поскольку они оба являются POD, это уничтожение фактически не имеет никакого эффекта.
Однако если бы number и o имели нетривиальные деструкторы, то number был бы уничтожен до o. Тот факт, что number является статическим членом класса o, не дает ему особого отношения к порядку уничтожения.
Если o выключен в другом исходном файле, то порядок построения не указан, а порядок уничтожения является обратным порядком построения (опять же, это если у них были нетривиальные деструкторы - int является особым случаем, поскольку это не так).
Ответ 4 · рейтинг 3 · Mike Seymour
Да, по двум причинам:
Он имеет статическую продолжительность хранения, поэтому его хранение длится в течение всего времени жизни программы.
У него есть тип без конструктора, инициализированный константным выражением.
В совокупности это означает, что он инициализируется на этапе статической инициализации до того, как запустится какой-либо пользовательский код (включая конструкторы статических объектов). Следовательно, он гарантированно существует и будет инициализирован до того, как какой-либо код сможет получить к нему доступ.
Если бы у него был конструктор или непостоянный инициализатор, то он был бы инициализирован во время динамической инициализации вместе со всеми другими такими объектами. В этом случае конструктор или инициализатор другого статического объекта может получить доступ к объекту до его инициализации. Эту проблему иногда называют "фиаско статического порядка инициализации".
Ответ 5 · рейтинг 1 · LihO
Стандарт гарантирует, что объекты с длительностью статического хранения существуют в течение всего времени работы программы.
C++03, 3.7.1 Длительность статического хранения §1:
Все объекты, которые не имеют динамической продолжительности хранения и не являются локальными, имеют статическую продолжительность хранения. Хранилище для этих объектов должно длиться в течение всего срока действия программы.
и в вашем примере также актуален §4:
Ключевое слово static, примененное к члену данных класса в определении класса, дает срок статического хранения члена данных.