Срок жизни глобальной переменной C ++ - PullRequest
2 голосов
/ 11 апреля 2011

У меня есть глобальная переменная, которая является экземпляром класса.Этот класс создал изображение в своем конструкторе (directX).

Проблема в том, что я получаю нарушение прав доступа во время выполнения, но код компилируется.Я думаю, проблема в том, что конструктор класса вызывается до инициализации, выполняемой в функции winmain.

, поэтому я хочу знать, что

  1. кто-нибудь сталкивался с этой проблемой и знает решение.

  2. Что такоевремя жизни глобала, я знаю, что переменные, объявленные в функции, теряются после ее возвращения, и что компилятор просматривает код, чтобы увидеть, соответствует ли все, именно поэтому мы должны создавать прототипы функций, но где глобальные элементы входят в уравнение.

Ответы [ 4 ]

4 голосов
/ 11 апреля 2011

Возможно, вы захотите взглянуть на что-то вроде одноэлементного шаблона , если вы действительно хотите иметь один экземпляр глобального объекта, который можно инициализировать после завершения инициализации (по сути, изображение будет создано При первом обращении к нему вы будете использовать предварительно созданную версию).

Глобалы создаются (в неопределенном порядке) до вызова вашего winmain. Они остаются там до тех пор, пока ваша программа не выйдет (в этот момент я считаю, что деструкторы вызываются в неопределенном порядке) ..

Другой (возможно, более простой) альтернативой, которую вы могли бы использовать, было бы изменение вашего global с экземпляра класса на указатель на него ... тогда вы бы получили что-то вроде:

// global...
MyGlobalClass *bigGlobalImageHolder;

// Winmain
// Perform directX setup (don't know what that is)
// Create the image class
bigGlobalImageHolder = new MyGlobalClass();


// do the rest of your stuff...  I'm guessing enter some kind of event loop

// clean up your global
delete bigGlobalImageHolder;
// exit your winmain (and application)

Тогда везде, где вы в данный момент ссылаетесь на свой глобальный объект, вы можете вместо этого ссылаться на него через указатель.

 // so
 bigGlobalImageHolder.GetImage();
 // becomes
 bigGlobalImageHolder->GetImage();
0 голосов
/ 11 апреля 2011

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

Проблема в том, что порядок, в котором происходит инициализация / уничтожение, не всегда детерминирован и, конечно, не переносим (т.е. зависит от платформы и, например, компоновщиков времени выполнения).

Наихудшая ситуация с разделяемым объектом (динамическое связывание). Некоторые платформы позволяют использовать флаги компоновщика для указания «приоритетов» для общих объектов (чтобы можно было влиять на статический порядок инициализации); Другие платформы (например, AIX gcc, HP / UX) требуют специальных атрибутов компилятора, чтобы пометить статические процедуры как «процедуры инициализации dll».


Короче говоря: не зависят от статических данных, кроме как через функции доступа. Функция доступа может выглядеть так:

 static int _myinternalvar = 3;
 static int GetMyInternalVar()
 {
      return _myinternalvar;
 }

таким образом, вы будете точно знать, , что статический объект был инициализирован до выполнения функции. Если метод доступа является единственной функцией, которая может получить доступ к данным, вы можете объявить статическое в своей области (добавление инкапсуляции).

0 голосов
/ 11 апреля 2011
  1. Я столкнулся с этой проблемой;Какой бы код ни использовался в этом class constructor, он должен быть инициализирован до запуска class constructor.Предположим, если другие переменные также являются глобальными, их конструктор должен быть вызван первым.Хотя конструкторы для global переменных вызываются неопределенным образом, вы можете использовать только небольшую работу: определите зависимые глобальные переменные в тех же файлах в порядке от наименее зависимого к самому зависимому.продолжительность жизни вашей программы
0 голосов
/ 11 апреля 2011

Похоже, вы испытываете "фиаско статического порядка инициализации".

Проверьте это это и следующие часто задаваемые вопросы.

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

...