Вот пример:
while (i < 10)
{
int j = 1;
string k = "hello.";
}
j является примитивным типом данных, а k является объектом. В соответствии с Есть ли у встроенных типов конструкторы по умолчанию?,
Таким образом, не классовые типы (включая фундаментальные типы, типы массивов,
ссылочные типы, типы указателей и типы enum) не имеют
Конструкторы.
И согласно Объявление переменных внутри циклов, хорошая практика или плохая практика? (2 Партера),
конструктор и деструктор должны выполняться на каждой итерации в
случай объекта (например, std :: string).
Тем не мение, объявление переменной в цикле while C / C ++ говорит,
while(i--) { int i=100; // gets created every time the loop is entered i--; printf("%d..",i); } // the i in the loop keeps getting destroyed here
Я узнал, что когда вызывается функция (например, main()
операционной системой), все локальные переменные создаются в начале функции и уничтожаются в конце функции. Выше цитата цикла while говорит, что примитивный тип данных i
создается, когда он объявляется в блоке цикла while и уничтожается в конце блока цикла while для каждой итерации.
Это правда? # 1 Выделяются ли примитивные типы данных, объявленные в блоке while, для каждой итерации цикла while? # 2 Неправильно ли я считать, что эти объявления в цикле while должны создаваться в начале функции, в которой содержится блок while?
Я ищу подробное объяснение, а не просто да или нет.
Логически, да, переменные создаются в начале тела цикла для каждой итерации цикла и уничтожаются в конце.
В вашем первом примере конструктор std::string
(на самом деле std::basic_string<char>
который является то, что std::string
is) будет вызываться для каждой итерации, как и деструктор. так же j
создается и устанавливается 1
за каждую итерацию.
Во втором примере i
будет напечатан со значением 99
по той же причине.
Компиляторы имеют некоторую свободу действий в этом. Если они могут обнаружить отсутствие эффекта повторного создания и уничтожения, они могут поддерживать переменную в рабочем состоянии и просто повторно инициализировать ее для каждой итерации цикла. Они могут даже полностью исключить переменные (например, просто вывести 99 повторно, а не создавать переменную). Однако на такие вещи нельзя полагаться, и программа не может проверить, чтобы увидеть, происходит ли это.
Программа должна вести себя как будто он перераспределяется (и затем освобождается) каждый раз через цикл.
Механизм, с помощью которого программа демонстрирует такое поведение, полностью зависит от компилятора. Во многих случаях для переменной вообще не будет выделено место, или она может вообще не существовать! (такие как j
в вашем первом примере)
Если пространство выделяется, я думаю, что типично, что пространство резервируется, когда вызывается функция, содержащая цикл. (и это пространство не обязательно исключительно зарезервированный)
Да, когда вы объявляете переменную внутри цикла, программа ведет себя как будто переменная создавалась и уничтожалась на каждой итерации цикла. Так что если переменная имеет тип класса, программа ведет себя как будто его конструктор и деструктор вызывались каждый раз.
Однако, благодаря оптимизации, ненаблюдаемое поведение может быть удалено, поэтому первый цикл можно просто полностью оптимизировать, а второй цикл можно оптимизировать до чего-то вроде
while(i--)
printf("%d..", 99);
Так что может случиться так, что фактическая переменная не будет создана.