C ++

Время жизни объекта и продолжительность хранения в C ++

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

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

Остальная часть этой статьи иллюстрирует время жизни объекта и кратко объясняет различную продолжительность хранения. Вы должны иметь базовые знания в C ++, чтобы понять эту статью. Вы также должны обладать знаниями в области C ++.

Содержание статьи

Иллюстрация времени жизни объекта

Рассмотрим следующую программу:

#включать
используя пространство имен std;
int main ()

если (1 == 1)

int x;
х = 1;
char y;
у = 'А';
cout << x << y << '\n';

возврат 0;

На выходе 1А .

Срок службы объекта подходит к концу, когда он выходит за пределы области видимости. Время жизни объекта x начинается с «x = 1;» и заканчивается в конце if-local-scope. Время жизни объекта y начинается с «y = 'A';» и заканчивается в конце if-local-scope. Прежде чем оба объекта умрут, они используются в операторе cout .

Срок хранения

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

Автоматическая продолжительность хранения

Если переменная не объявлена ​​явно как static, thread_local или extern, тогда эта переменная имеет автоматическую продолжительность хранения. Примеры: x и y выше. Срок действия таких переменных заканчивается, когда они выходят за пределы области видимости. Следующая программа иллюстрирует автоматическую продолжительность хранения для ссылки и указателя в глобальной области видимости.

#включать
используя пространство имен std;
int x = 1;
int & m = x;
char y = 'A';
символ * п = & y;
int main ()

cout << m << *n << '\n';
возврат 0;

На выходе 1А .

Продолжительность m начинается с «int & m = x;» и заканчивается в конце программы. Продолжительность n начинается с «char * n = & y;» и заканчивается в конце программы.

Продолжительность динамического хранения

Бесплатный магазин

На современном компьютере одновременно может работать более одной программы. Каждая программа имеет свой участок памяти. Остальная часть памяти, которая не используется какой-либо программой, называется свободным хранилищем. Следующее выражение используется для возврата местоположения целого числа из бесплатного магазина

новый int

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

int * ptrInt = новый int;
* ptrInt = 12;
cout<< *ptrInt <<'\n';

Выход 12 .

Чтобы положить конец жизни объекта, используйте выражение удаления следующим образом:

удалить ptrInt;

Аргументом для выражения удаления является указатель. Следующий код иллюстрирует его использование:

int * ptrInt = новый int;
* ptrInt = 12;
удалить ptrInt;

Указатель, созданный с новым выражением и удаленный с помощью выражения удаления, имеет длительность динамического хранения. Этот указатель умирает, когда выходит за пределы области видимости или удаляется. Продолжительность объекта в предыдущем коде начинается с «* ptrInt = 12;» и заканчивается в конце декларативной области (области). Выражения new и delete - это нечто большее, чем обсуждалось здесь - см. Ниже.

Статическая продолжительность хранения

Статический объект

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

Рассмотрим следующую программу, которая должна считать от 1 до 5 (не тестируйте программу):

#включать
используя пространство имен std;
int fn ()

int stc = 1;
cout << " << stc;
stc = stc + 1;
если (stc> 5)
возврат 0;
fn ();

int main ()

fn ();
возврат 0;

На выходе получается 1 1 1 1 1 1 1 1… и никогда не заканчивается. Определение функции - это повторяющаяся функция; это означает, что он продолжает вызывать себя, пока не будет выполнено условие.

Решение состоит в том, чтобы сделать объект stc статическим. После инициализации статического объекта его значение нельзя изменить, пока программа не завершится. Следующая программа (которую вы можете протестировать), которая аналогична предыдущей, но теперь с stc, сделанной статической, считает от 1 до 5:

#включать
используя пространство имен std;
int fn ()

статический int stc = 1;
cout << " << stc;
stc = stc + 1;
если (stc> 5)
возврат 0;
fn ();

int main ()

fn ();
возврат 0;

Результат: 1 2 3 4 5 .

Примечание: продолжительность статического объекта начинается, когда объект был инициализирован, и заканчивается в конце программы. А пока объект можно использовать косвенно, из другой области видимости. После инициализации статического объекта его начальное значение не может быть изменено, даже если его определение повторно оценивается. В приведенном выше коде stc не сбрасывается, при следующем вызове. При следующем вызове он увеличивается на «stc = stc + 1;».

Статический элемент данных

Набор связанных переменных и функций можно поместить в обобщенный блок, называемый классом. Если переменным присваиваются определенные значения, класс становится объектом. Однако объект не создается путем простого присвоения значений переменной. Класс создается для получения объекта; и каждый созданный объект имеет собственное имя, отличное от других объектов того же класса. Следующая программа показывает класс с именем TheCla и объект с именем obj; он также показывает, как объект создается и используется в функции main ():

#включать
используя пространство имен std;
класс TheCla

общественность:
int num;
void func (char cha, const char * str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

;
int main ()

TheCla obj;
объект.число = 12;
объект.func ('$', «500»);
возврат 0;

Результат:

В магазине 12 книг стоимостью 500 долларов.

Обратите внимание, что для того, чтобы присвоить значение 12 переменной num, объект должен быть создан до того, как присвоение могло произойти. Программист может присвоить значение без инстанцирования (создания) объекта. Для этого переменная num должна быть объявлена ​​как статическая. Тогда он будет доступен как «TheCla :: num» без имени объекта, но с именем класса. Следующая программа иллюстрирует это:

#включать
используя пространство имен std;
класс TheCla

общественность:
статическая константа int num = 12;
void func (char cha, const char * str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

;
int main ()

cout << TheCla::num << '\n';
TheCla obj;
объект.func ('$', «500»);
возврат 0;

Результат:

12
В магазине 12 книг стоимостью 500 долларов.

Обратите внимание, что для доступа к элементу данных num в main () необходимо было использовать оператор разрешения области видимости ::. Также не то, чтобы переменную num нужно было сделать постоянной и инициализировать в описании (определении) класса.

Статическая функция-член

Обратите внимание, что в предыдущем листинге программы выше, чтобы использовать функцию func в main (), необходимо было создать экземпляр объекта. Программист может вызвать функцию без инстанцирования (создания) объекта. Для этого перед определением функции должно стоять слово «статический». Тогда он будет доступен как «TheCla :: func ()» без имени объекта, но с именем класса. Следующая программа иллюстрирует это для статических данных-членов и статических функций-членов:

#включать
используя пространство имен std;
класс TheCla

общественность:
статическая константа int num = 12;
статическая функция void (char cha, const char * str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

;
int main ()

TheCla :: func ('$', "500");
возврат 0;

Результат:

В магазине 12 книг стоимостью 500 долларов.

Продолжительность хранения потока

Поток как функция в C ++ еще не реализован компилятором g ++. Итак, вместо объяснения этого цитата из спецификации C ++ дается следующим образом:

  1. Все переменные, объявленные с ключевым словом thread_local, имеют продолжительность хранения потока. Хранение этих объектов должно длиться в течение всего потока, в котором они созданы. Для каждого потока существует отдельный объект или ссылка, и использование объявленного имени относится к сущности, связанной с текущим потоком.
  2. Переменная с длительностью хранения потока должна быть инициализирована перед первым использованием odr и, если она создана, должна быть уничтожена при выходе из потока.”

Заключение

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

Chrys

Как показать счетчик FPS в играх для Linux
Игры для Linux получили серьезный толчок, когда Valve объявила о поддержке Linux для клиента Steam и своих игр в 2012 году. С тех пор многие игры AAA ...
Как загрузить и играть в Sid Meier's Civilization VI в Linux
Введение в игру Civilization 6 - это современный подход к классической концепции, представленной в серии игр Age of Empires. Идея была довольно просто...
Как установить Doom и играть в него в Linux
Введение в Doom Серия Doom возникла в 90-х годах после выхода оригинальной Doom. Это мгновенно стал хитом, и с тех пор серия игр получила множество на...