Время жизни объекта
Эта статья нуждается в дополнительных цитатах для проверки . ( январь 2013 г. ) |
В объектно-ориентированном программировании (ООП) срок жизни объекта — это период времени между объекта созданием и его уничтожением. В некоторых контекстах программирования время жизни объекта совпадает со временем жизни переменной , представляющей объект. В других контекстах, где доступ к объекту осуществляется по ссылке , время жизни объекта не определяется временем жизни переменной. Например, уничтожение переменной может уничтожить только ссылку; не указанный объект.
Терминология
[ редактировать ]Аспекты времени жизни объекта различаются в зависимости от языка программирования и внутри реализации языка. Основные концепции относительно распространены, но терминология различается. Например, концепции создания и уничтожения иногда называют конструкцией и уничтожением , а элементы языка называются конструктором (ctor) и деструктором (dtor).
Детерминизм
[ редактировать ]Создание объекта обычно является детерминированным , но уничтожение зависит от контекста программирования. Некоторые контексты допускают детерминированное разрушение, но некоторые — нет. Примечательно, что в среде сбора мусора объекты уничтожаются по выбору сборщика мусора.
Синтаксис создания и уничтожения зависит от контекста программирования. Во многих контекстах, включая C++, C# и Java, объект создается с помощью специального синтаксиса, например new typename()
. В C++, который обеспечивает ручное управление памятью , объект уничтожается с помощью delete
ключевое слово. В C# и Java, без явного синтаксиса уничтожения, сборщик мусора автоматически и недетерминированно уничтожает неиспользуемые объекты.
на объект Альтернативный и детерминированный подход к автоматическому уничтожению заключается в том, что объект уничтожается, когда код уменьшает счетчик ссылок до нуля.
В пуле объектов , где объекты могут быть созданы заранее и повторно использованы, кажущееся создание и уничтожение объекта может не соответствовать фактическому. Пул обеспечивает повторную инициализацию для создания и финализацию для уничтожения. И создание, и разрушение могут быть недетерминированными.
Объекты со статическим распределением памяти имеют время жизни, которое совпадает с запуском программы, но порядок создания и уничтожения различных статических объектов обычно недетерминирован.
Жизненный цикл
[ редактировать ]объекта Жизненный цикл относится к событиям, которые испытывает объект, включая создание и уничтожение.
Жизненный цикл обычно включает управление памятью и операции после выделения и перед освобождением. Создание объекта обычно состоит из выделения памяти и инициализации, причем инициализация включает присвоение значений полям и запуск кода инициализации. Уничтожение объекта обычно состоит из финализации (очистки) и освобождения памяти (освобождения). Эти шаги обычно выполняются в следующем порядке: выделение, инициализация, завершение, освобождение.
В зависимости от контекста программирования эти шаги могут быть частично или полностью автоматизированы, а некоторые из них можно настроить.
Частота настройки обычно зависит от шага и контекста программирования. Инициализация — это наиболее часто настраиваемый шаг. Финализация распространена в языках с детерминированным разрушением, особенно в C++, но редко встречается в языках со сборкой мусора. Выделение редко настраивается, а освобождение, как правило, не может быть настроено.
Создание
[ редактировать ]
Способ создания объектов различается в зависимости от контекста программирования. В некоторых языках на основе классов конструктор инициализацию выполняет . Как и другие методы, конструктор можно перегрузить , чтобы поддерживать создание с другим начальным состоянием.
Разрушение
[ редактировать ]
Обычно объект удаляется из памяти после того, как он больше не нужен. Однако если памяти достаточно или программа работает мало, уничтожение объекта может не произойти; память просто освобождается при завершении процесса.
В некоторых случаях уничтожение объекта состоит исключительно из освобождения памяти, особенно при сборке мусора, или если объект представляет собой обычную старую структуру данных . В других случаях очистка выполняется перед освобождением, в частности, уничтожаются объекты-члены (при ручном управлении памятью) или удаляются ссылки из объекта на другие объекты для уменьшения счетчика ссылок (при подсчете ссылок). Это может происходить автоматически или к объекту может быть вызван специальный метод уничтожения.
В языках на основе классов с детерминированным временем жизни объекта, особенно в C++, деструктор вызывается при удалении экземпляра до освобождения памяти. В C++ деструкторы во многом отличаются от конструкторов. Они не могут быть перегружены, не должны иметь аргументов, не требуют поддержки инвариантов классов и могут привести к завершению программы, если создают исключения.
При сборке мусора объекты могут быть уничтожены, когда программа больше не сможет получить к ним доступ. Сборщик мусора вызывает финализатор перед освобождением памяти.
Уничтожение объекта приведет к тому, что любые ссылки на объект станут недействительными. При ручном управлении памятью любая существующая ссылка становится висячей ссылкой . При сборке мусора объекты уничтожаются только тогда, когда на них нет ссылок.
Последовательность
[ редактировать ]Срок службы объекта начинается, когда завершается выделение, и заканчивается, когда начинается освобождение. Таким образом, во время инициализации и финализации объект жив, но может находиться в несогласованном состоянии. Период между завершением инициализации и началом финализации — это когда объект одновременно активен и находится в согласованном состоянии.
В случае сбоя создания или уничтожения отчет об ошибках (например, создание исключения) может быть затруднен, поскольку объект или связанные объекты могут находиться в несогласованном состоянии.
Для статической переменной , срок жизни которой совпадает с временем выполнения программы, ошибка создания или уничтожения является проблематичной, поскольку выполнение программы происходит до или после нормального выполнения.
Программирование на основе классов
[ редактировать ]В программировании на основе классов создание объекта также известно как экземпляра (создание экземпляра класса создание ). Создание и уничтожение можно настроить с помощью конструктора и деструктора , а иногда и с помощью отдельных методов инициализатора и финализатора .
Примечательно, что конструктор является методом класса, поскольку объект (экземпляр) не доступен до тех пор, пока объект не будет создан, но деструкторы, инициализаторы и финализаторы являются методами экземпляра.
Кроме того, конструкторы и инициализаторы часто могут принимать аргументы, тогда как деструкторы и финализаторы обычно этого не делают, поскольку они часто могут быть вызваны неявно.
Управление ресурсами
[ редактировать ]В языках с детерминированными объектами времени жизни время жизни может использоваться для управления ресурсами . Это называется идиомой «Приобретение ресурсов — это инициализация» (RAII). Ресурсы приобретаются во время инициализации и освобождаются во время финализации. В языках с недетерминированными объектами времени существования (т. е. со сборкой мусора) управление памятью обычно отделяется от управления другими ресурсами.
Примеры
[ редактировать ]С++
[ редактировать ]Класс C++ может быть объявлен со значениями по умолчанию следующим образом:
class Foo {};
При объявлении в автоматическом контексте объект уничтожается при закрытии объявленного блока.
int bar() {
Foo foo();
// foo is destroyed here
}
Созданный динамически, он живет до тех пор, пока не будет явно уничтожен.
int bar() {
Foo *pFoo = new Foo();
delete pFoo;
}
Ява
[ редактировать ]Класс Java может быть объявлен со значениями по умолчанию следующим образом:
class Foo {}
После создания экземпляра (т. е. new Foo()
) он живет до тех пор, пока на него не закончатся ссылки и сборщик мусора не удалит его.