Каково время жизни статических переменных класса В C++?

Если у меня есть класс под названием Test::

class Test
{
    static std::vector<int> staticVector;
};

когда staticVector получить построен и когда он получает разрушен ?

это с создания первого объекта класса Test, или просто как обычные статические переменные ?

чтобы уточнить, этот вопрос пришел мне на ум после прочтения концепций языков программирования (Sebesta Ch-5.4.3.1), и он говорит ::

обратите внимание, что когда статический модификатор появляется в объявлении переменная в определении класса В C++, Java и C#, это не имеет ничего общего с время жизни переменной. В том контекст, это означает, что переменная переменная класса, а не переменная экземпляра. Многократное использование зарезервированное слово может сбивать с толку особенно для тех, кто изучает язык.

вы поняли? :(

6 ответов


точно так же, как регулярные статические (глобальные) переменные.


я тоже хочу написать текст об initializaton, на который я могу позже ссылаться.


сначала список возможностей.

  • пространство имен Static
  • класс Static
  • местные Static

Пространство Имен Static

  • существует два метода инициализации. static (должно произойти во время компиляции) и динамический (предназначено для выполнения во время выполнения) инициализация.
  • Static инициализации происходит перед любая динамическая инициализация, без учета отношений единиц перевода.
  • динамический инициализация упорядочена в единице перевода, в то время как в статической инициализации нет особого порядка. Объекты области пространства имен одной и той же единицы перевода динамически инициализируются в порядке который их определения.
  • объекты типа POD, которые инициализируются постоянными выражениями, статически инициализируются. На их значение можно положиться при динамической инициализации любого объекта, не обращая внимания на отношения единиц перевода.
  • если инициализация вызывает исключение,std::terminate называется.

примеры:

следующая программа печатает A(1) A(2)

struct A { 
  A(int n) { std::printf(" A(%d) ", n); } 
};

A a(1);
A b(2);

и следующий, основанный на том же классе, печатает A(2) A(1)

extern A a;
A b(2);
A a(1);

давайте представим, что есть единица перевода, где msg определяется следующим образом

char const *msg = "abc";

затем следующие выводит abc. Обратите внимание, что p получает динамическую инициализацию. Но потому что статическая инициализация (char const* тип РМО и "abc" является постоянным выражением адреса)msg происходит до этого, это нормально, и msg is гарантируется правильная инициализация.

extern const char *msg;
struct P { P() { std::printf("%s", msg); } };
P p;
  • динамический инициализация объекта не требуется, чтобы произойти до main любой ценой. Однако инициализация должна произойти до первого использования объекта или функции его единицы перевода. Это важно для динамических загружаемых библиотек.

Статический Класс

  • вести себя как статика пространства имен.
  • есть сообщение об ошибке разрешено ли компилятору инициализировать статику класса при первом использовании функции или объекта ее единицы перевода (после main). Формулировка в стандарте в настоящее время позволяет это только для объектов области пространства имен, но, похоже, она намерена разрешить это и для объектов области классов. Читать объекты области пространства имен.
  • для статики классов, являющихся членами шаблонов, правило заключается в том, что они инициализируются только в том случае, если они когда-либо использовались. Не используя их не поддаваться инициализации. Обратите внимание, что в любом случае инициализация произойдет, как описано выше. Инициализация не будет отложена, поскольку она является членом шаблона.

Локальные Статические

  • для локальной статики существуют специальные правила.
  • объекты типа POD, инициализированные постоянным выражением, инициализируются до ввода их блока, в котором они определены.
  • другие локальные статические объекты инициализируются в первый раз контроль проходит через их определение. Инициализация не считается завершенной при возникновении исключения. Инициализация будет повторена в следующий раз.

пример: следующая программа печатает 0 1:

struct C { 
  C(int n) { 
    if(n == 0)
      throw n;
    this->n = n;
  }
  int n;
};

int f(int n) {
  static C c(n);
  return c.n;
}

int main() {
  try { 
    f(0); 
  } catch(int n) { 
    std::cout << n << " "; 
  }
  f(1); // initializes successfully
  std::cout << f(2);  
}

во всех вышеперечисленных случаях, в некоторых ограниченных случаях, для некоторых объектов, которые не требуется инициализировать статически, компилятор может статически инициализировать его, а не динамическая инициализация. Это сложная проблема, см. ответ для более подробного примера.

также отметим, что порядок уничтожения-это точный порядок завершения строительства объектов. Это распространено и происходит во всех ситуациях на C++, в том числе при разрушении временных файлов.


Он строится в то же время, когда глобальные переменные строятся и разрушаются вместе с глобалами.


проще говоря:
При построении глобальных переменных создается статическая переменная-член. Порядок построения глобальных переменных не определен, но это происходит до ввода основной функции.

разрушение происходит, когда глобальные переменные уничтожаются.

глобальные переменные разрушаются в обратном порядке, они были построены; после выхода из основной функции.

с уважением,
Ованес!--2-->

P. S.: Я предложите взглянуть на C++-Standard, который объясняет (определяет), как и когда создаются или разрушаются глобальные или статические переменные-члены.

P. P. S.: ваш код объявляет только статическую переменную-член, но не инициализирует ее. Чтобы инициализировать его, вы должны написать в одном из блоков компиляции:

std:: векторный тест:: статиквектор;
или
std:: векторный тест:: staticVector=std:: vector (/*ctor здесь*/);


некоторая конкретная информация VC++ в случае, если это то, что вы используете:

  1. статические переменные класса построение происходит одновременно с другими статическими / глобальными переменными.
  2. в windows, функция запуска CRT отвечает за эту конструкцию. Это фактическая точка входа большинства программ, которые вы компилируете (это функция, которая вызывает вашу функцию Main/Winmain). Кроме того, он отвечает за инициализацию всей поддержки среды выполнения C (например, вы нужно использовать malloc).
  3. порядок построения не определен, однако при использовании компилятора microsoft VC порядок построения для основных типов будет в порядке, например это законно и безопасно писать

статика.ч: ... Объявление класса MyClass ... статический const int a; статические инт б; статический int ar[]; } статика.cpp:

const int MyClass::a = 2;
int MyClass::b = a+3;
int MyClass::ar[a] = {1,2}

статическая переменная-член класса означает, что, хотя существует несколько объектов одного класса, переменная будет одинаковой для всех объектов класса.

Итак, я бы сказал, что он строится, когда первый объект создается и разрушается, когда последний объект разрушается.