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

Два стека в очереди определены как stack1 и stack2 .

Enqueue: euqueued элементы всегда помещаются в stack1

Dequeue: Верхняя часть stack2 может быть выдвинутым, поскольку это первый элемент, вставленный в очередь, когда stack2 не пуст. Когда stack2 пусто, мы извлекаем все элементы из stack1 и помещаем их в stack2 по одному. Первый элемент в очереди помещается в нижнюю часть stack1 . Его можно вытолкнуть сразу после операций выталкивания и нажатия, поскольку он находится на вершине стека stack2 .

Ниже приведен тот же пример кода C ++:

template  class CQueue
{
public:
    CQueue(void);
    ~CQueue(void);

    void appendTail(const T& node); 
    T deleteHead();                 

private:
    stack stack1;
    stack stack2;
};

template void CQueue::appendTail(const T& element) {
    stack1.push(element);
} 

template T CQueue::deleteHead() {
    if(stack2.size()<= 0) {
        while(stack1.size()>0) {
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }


    if(stack2.size() == 0)
        throw new exception("queue is empty");


    T head = stack2.top();
    stack2.pop();


    return head;
}

Это решение заимствовано из моего блога . Более подробный анализ с пошаговым моделированием работы доступен на моей странице в блоге.

11
задан AraK 3 July 2009 в 16:50
поделиться

5 ответов

Многопоточность недоступна в стандартном PHP, но возможно параллельное программирование с использованием HTTP-запросов в качестве асинхронных вызовов.

При установке таймаута curl на 1 и использовании один и тот же session_id для процессов, которые вы хотите связать друг с другом, вы можете общаться с переменными сеанса, как в моем примере ниже. С помощью этого метода вы даже можете закрыть браузер, и параллельный процесс все еще существует на сервере.

Не забудьте проверить правильный идентификатор сеанса следующим образом:

http: //localhost/test/verifysession.php? sessionid = [ правильный идентификатор]

startprocess.php

$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];

process1.php

set_time_limit(0);

if ($_REQUEST["sessionid"])
   session_id($_REQUEST["sessionid"]);

function checkclose()
{
   global $_SESSION;
   if ($_SESSION["closesession"])
   {
       unset($_SESSION["closesession"]);
       die();
   }
}

while(!$close)
{
   session_start();
   $_SESSION["test"] = rand();
   checkclose();
   session_write_close();
   sleep(5);
}

verifysession.

13
ответ дан 3 December 2019 в 01:39
поделиться

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


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

  • Пространство имен Статический
  • Класс ] Статический
  • Локальный Статический

Пространство имен Статическое

  • Существует два метода инициализации. статическая (предназначена для выполнения во время компиляции) и динамическая (предназначена для выполнения во время выполнения) инициализации.
  • Статическая Инициализация происходит перед любой динамической инициализацией, без учета отношений единиц перевода.
  • Динамическая Инициализация упорядочивается в единицах трансляции, в то время как в статической инициализации нет определенного порядка. Объекты области пространства имен одной и той же единицы трансляции динамически инициализируются в том порядке, в котором появляются их определения.
  • Объекты типа 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 * является типом POD, а «abc» - выражение адресной константы) msg происходит до этого, это нормально, и msg гарантированно правильно инициализирован.

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

Class Static

  • Вести себя как статика пространства имен.
  • Имеется сообщение об ошибке о том, разрешено ли компилятору инициализировать статику класса при первом использовании функции или объекта его единицы трансляции (после 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 ++, в том числе при разрушении временных файлов.

см. этот ответ для более подробного примера.

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

см. этот ответ для более подробного примера.

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

17
ответ дан 3 December 2019 в 01:39
поделиться

Он создается одновременно с созданием и уничтожением глобальных переменных вместе с глобальными переменными.

5
ответ дан 3 December 2019 в 01:39
поделиться

Some specific VC++ information in case that's what you're using:

  1. Static class variables construction occurs at same time as other static/global variables.
  2. In windows, the CRT startup function is responsible for this construction. Это фактическая точка входа для большинства программ, которые вы компилируете (это функция, которая вызывает вашу функцию Main / Winmain). Кроме того, он отвечает за инициализацию всей поддержки среды выполнения C (например, она нужна вам для использования malloc).
  3. Порядок построения не определен, однако при использовании компилятора Microsoft VC порядок построения для базовых типов будет следующим: Хорошо, например, разрешено и безопасно писать

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

const int MyClass::a = 2;
int MyClass::b = a+3;
int MyClass::ar[a] = {1,2}
1
ответ дан 3 December 2019 в 01:39
поделиться

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

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

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

С уважением,
Ованес

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

PPS: Ваш код объявляет только статические переменные-члены, но не инициализирует его. Для его инициализации вы должны написать в одном из модулей компиляции:

std :: vector Test :: staticVector;
или
std :: vector Test :: staticVector = std :: vector (/ * здесь параметры ctor * /);

3
ответ дан 3 December 2019 в 01:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: