нулевая инициализация и статическая инициализация статической переменной локальной области

Я прочитал несколько постов на инициализация C++ из Google, некоторые из которых направляют меня сюда на StackOverflow. Концепции, которые я выбрал из этих сообщений, следующие:

  • The ордер инициализации C++ является:
    1. Ноль Инициализации;
    2. Статическая Инициализация;
    3. Динамическая Инициализация.
  • статический объекты (переменные включены) первого ноль-инициализировать, а потом Static-инициализировано.

у меня есть несколько запросов к инициализации вопрос (хранение класс проблема может быть связана а):

  • глобальные объекты (определенными без статический ключевое слово) также являются статическими объектами, верно?
  • глобальные объекты также инициализируется как статические объекты двумя шагами, как выше, верно?
  • Что такое Статическая Инициализация? Относится ли это к инициализации статических объектов (определенных с помощью статический ключевое слово)?
  • я тоже читала, что объекты, определенные в блоке (т. е. в функции) с статический ключевое слово инициализируется, когда поток сначала поступает в блок! Это значит, что локальные статические объекты не инициализируются перед main выполнение функции. Это означает, что они не инициализируются как два шага, упомянутых выше, верно?
  • динамическая инициализация относится к инициализации объектов, созданных новая оператор, верно? Это может относиться к инициализации как myClass obj = myClass(100); или myClass obj = foo();

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

Я надеюсь, вы дадите мне ответ, что логически объясняет всю карту спецификатора и инициализации класса хранения. Любая ссылка приветствуется!

код, который может объяснить мой вопрос:

class myClass{
public:
   int i;
   myClass(int j = 10): j(i){}
   // other declarations
};

myClass obj1;//global scope
static myClass obj2(2);//file scope
{   //local scope
   myClass obj3(3);
   static myClass obj4(4);
}

редактировать:
Если вы считаете, что мой вопрос довольно утомителен, вы можете помочь объяснить свои идеи на основе кода выше.

2 ответов


Я прочитал несколько постов на инициализация C++ из Google, некоторые из которых направляют меня сюда на StackOverflow. Концепции, которые я выбрал из этих сообщений, следующие:

  • на ордер инициализации C++ является:
    1. Ноль Инициализации;
    2. Статическая Инициализация;
    3. Динамическая Инициализация.

Да, действительно есть 3 фазы (стандартные). Давайте проясним их, прежде чем продолжить:

  • нулевая инициализация: память заполняется 0s на уровне байтов.
  • постоянная инициализация: предварительно вычисленный (во время компиляции) байтовый шаблон копируется в расположение памяти объекта
  • статическая инициализация: нулевая инициализация с последующей постоянной инициализацией
  • динамический Инициализация: функция выполняется для инициализации памяти

простой пример:

int const i = 5;     // constant initialization
int const j = foo(); // dynamic initialization
  • статические объекты (переменные включены) первого ноль-инициализировать, а потом Static-инициализировано.

да и нет.

стандартные мандаты, чтобы объекты были сначала инициализированы нулем, а затем они:

  • постоянная инициализировано, если возможно
  • динамически инициализируется иначе (компилятор не смог вычислить содержимое памяти во время компиляции)

Примечание: В случае постоянной инициализации компилятор может пропустить первую нулевую инициализированную память, следуя правилу as-if.

у меня есть несколько запросов к инициализации вопрос (хранение класс проблема может быть связана а):

  • глобальные объекты (определенными без статический ключевое слово) также являются статическими объектами, верно?

да, в области файла


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

Первый: Инициализации

когда переменная выделяется в памяти, типичные процессоры оставляют память нетронутой, поэтому переменная будет иметь то же значение, что и кто-то другой, сохраненный ранее. Для обеспечения безопасности некоторые компиляторы добавляют дополнительный код для инициализации всех переменных, которые они выделяют в ноль. Я думаю, это это то, что вы подразумеваете под "нулевой инициализацией". Это происходит, когда вы говорите:

 int i; // not all compilers set this to zero

однако, если вы скажете компилятору:

 int i = 10;

затем компилятор инструктирует процессор поместить 10 в память, а не оставлять его со старыми значениями или устанавливать его в ноль. Я думаю, это то, что вы подразумеваете под "статической инициализацией".

наконец, вы можете сказать следующее:

 int i;
 ...
 ...
 i = 11;

затем процессор "инициализирует ноль" (или оставляет старое значение), когда выполнение int i; затем, когда он достигает линии i = 11 он "динамически инициализирует" переменную до 11 (что может произойти очень долго после первой инициализации.

Second: расположение переменной

существуют: переменные на основе стека (иногда называемые статическими переменными) и переменные кучи памяти (иногда называемые динамическими переменными).

переменные могут быть созданы в сегменте стека с помощью этого:

int i;

или куча памяти вот так:

int *i = new int;

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

третье: время инициализации переменной

переменная stack-segment "инициализируется нулем" или статически инициализируется " при вводе вызова функции, они определены в течение.

переменная кучи памяти "инициализируется нулем" или статически инициализируется", когда она впервые создается new оператора.

Последнее Замечание

вы можете думать о!--9--> как глобальная переменная с областью, ограниченной функцией, в которой она определена. Я думаю, путаница о static int i; приходит, потому что статический слух означает другое (он не разрушается при выходе из рутины, поэтому он сохраняет свою ценность). Я не уверен, но я думаю, что трюк используется для static int i; это положить его в стопку main() это означает, что он не уничтожается до тех пор, пока вы не выйдете из всей программы (поэтому он сохраняет первую инициализацию), или это может быть, что он хранится в сегменте данных приложения.