In
object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of pr ...
(OOP), the object lifetime (or life cycle) of an
object
Object may refer to:
General meanings
* Object (philosophy), a thing, being, or concept
** Object (abstract), an object which does not exist at any particular time or place
** Physical object, an identifiable collection of matter
* Goal, an ...
is the time between an object's
creation
Creation may refer to:
Religion
*''Creatio ex nihilo'', the concept that matter was created by God out of nothing
* Creation myth, a religious story of the origin of the world and how people first came to inhabit it
* Creationism, the belief tha ...
and its destruction. Rules for object lifetime vary significantly between
languages, in some cases between
implementations of a given language, and lifetime of a particular object may vary from one
run of the program to another.
In some cases, object lifetime coincides with
variable lifetime of a
variable
Variable may refer to:
* Variable (computer science), a symbolic name associated with a value and whose associated value may be changed
* Variable (mathematics), a symbol that represents a quantity in a mathematical expression, as used in many ...
with that object as value (both for
static variable
In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is ...
s and
automatic variables), but in general, object lifetime is not tied to the lifetime of any one variable. In many cases – and by default in many object-oriented languages, particularly those that use
garbage collection
Waste collection is a part of the process of waste management. It is the transfer of solid waste from the point of use and disposal to the point of treatment or landfill. Waste collection also includes the curbside collection of recyclabl ...
(GC) – objects are allocated on the
heap, and object lifetime is not determined by the lifetime of a given variable: the value of a variable holding an object actually corresponds to a ''
reference
Reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a '' name'' ...
'' to the object, not the object itself, and destruction of the variable just destroys the reference, not the underlying object.
Overview
While the basic idea of object lifetime is simple – an object is created, used, then destroyed – details vary substantially between languages, and within implementations of a given language, and is intimately tied to how
memory management
Memory management is a form of resource management applied to computer memory. The essential requirement of memory management is to provide ways to dynamically allocate portions of memory to programs at their request, and free it for reuse when ...
is implemented. Further, many fine distinctions are drawn between the steps, and between language-level concepts and implementation-level concepts. Terminology is relatively standard, but which steps correspond to a given term varies significantly between languages.
Terms generally come in antonym pairs, one for a creation concept, one for the corresponding destruction concept, like ''initialize/finalize'' or ''constructor/destructor.'' The creation/destruction pair is also known as ''initiation/termination,'' among other terms. The terms ''allocation'' and ''deallocation'' or ''freeing'' are also used, by analogy with memory management, though object creation and destruction can involve significantly more than simply memory allocation and deallocation, and allocation/deallocation are more properly considered steps in creation and destruction, respectively.
Determinism
A major distinction is whether an object's lifetime is deterministic or non-deterministic. This varies by language, and within language varies with the
memory allocation
Memory management is a form of resource management applied to computer memory. The essential requirement of memory management is to provide ways to dynamically allocate portions of memory to programs at their request, and free it for reuse when ...
of an object; object lifetime may be distinct from variable lifetime.
Objects with
static memory allocation
In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is ...
, notably objects stored in
static variable
In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is ...
s, and classes
modules
Broadly speaking, modularity is the degree to which a system's components may be separated and recombined, often with the benefit of flexibility and variety in use. The concept of modularity is used primarily to reduce complexity by breaking a s ...
(if classes or modules are themselves objects, and statically allocated), have a subtle non-determinism in many languages: while their lifetime appears to coincide with the run time of the program, the ''order'' of creation and destruction – which static object is created first, which second, etc. – is generally nondeterministic.
For objects with
automatic memory allocation or
dynamic memory allocation
Memory management is a form of resource management applied to computer memory. The essential requirement of memory management is to provide ways to dynamically allocate portions of memory to programs at their request, and free it for reuse when ...
, object creation generally happens deterministically, either explicitly when an object is explicitly created (such as via
new
in C++ or Java), or implicitly at the start of variable lifetime, particularly when the
scope
Scope or scopes may refer to:
People with the surname
* Jamie Scope (born 1986), English footballer
* John T. Scopes (1900–1970), central figure in the Scopes Trial regarding the teaching of evolution
Arts, media, and entertainment
* Cinem ...
of an
automatic variable is entered, such as at declaration. Object destruction varies, however – in some languages, notably C++, automatic and dynamic objects are destroyed at deterministic times, such as scope exit, explicit destruction (via
manual memory management
In computer science, manual memory management refers to the usage of manual instructions by the programmer to identify and deallocate unused objects, or garbage. Up until the mid-1990s, the majority of programming languages used in industry supp ...
), or
reference count
In computer science, reference counting is a programming technique of storing the number of references, pointers, or handles to a resource, such as an object, a block of memory, disk space, and others.
In garbage collection algorithms, referen ...
reaching zero; while in other languages, such as C#, Java, and Python, these objects are destroyed at non-deterministic times, depending on the garbage collector, and
object resurrection
In object-oriented programming languages with garbage collection, object resurrection is when an object comes back to life during the process of object destruction, as a side effect of a finalizer being executed.
Object resurrection causes a nu ...
may occur during destruction, extending the lifetime.
In garbage-collected languages, objects are generally dynamically allocated (on the heap) even if they are initially bound to an automatic variable, unlike automatic variables with primitive values, which are typically automatically allocated (on the stack or in a register). This allows the object to be returned from a function ("escape") without being destroyed. However, in some cases a
compiler optimization is possible, namely performing
escape analysis
In compiler optimization, escape analysis is a method for determining the dynamic scope of pointers where in the program a pointer can be accessed. It is related to pointer analysis and shape analysis.
When a variable (or an object) is allocate ...
and proving that escape is not possible, and thus the object can be allocated on the stack; this is significant in Java. In this case object destruction will occur promptly – possibly even during the variable's lifetime (before the end of its scope), if it is unreachable.
A complex case is the use of an
object pool
The object pool pattern is a software creational design pattern that uses a set of initialized objects kept ready to use – a "pool" – rather than allocating and destroying them on demand. A client of the pool will request an object from the po ...
, where objects may be created ahead of time or reused, and thus apparent creation and destruction may not correspond to actual creation and destruction of an object, only (re)initialization for creation and finalization for destruction. In this case both creation and destruction may be nondeterministic.
Steps
Object creation can be broken down into two operations: memory ''allocation'' and ''
initialization,'' where initialization both includes assigning values to object fields and possibly running arbitrary other code. These are implementation-level concepts, roughly analogous to the distinction between ''
declaration
Declaration may refer to:
Arts, entertainment, and media Literature
* ''Declaration'' (book), a self-published electronic pamphlet by Michael Hardt and Antonio Negri
* ''The Declaration'' (novel), a 2008 children's novel by Gemma Malley
Music ...
'' and ''definition'' of a variable, though these later are language-level distinctions. For an object that is tied to a variable, declaration may be compiled to memory allocation (reserving space for the object), and definition to initialization (assigning values), but declarations may also be for compiler use only (such as
name resolution), not directly corresponding to compiled code.
Analogously, object destruction can be broken down into two operations, in the opposite order: ''finalization'' and memory ''deallocation.'' These do not have analogous language-level concepts for variables: variable lifetime ends implicitly (for automatic variables, on stack unwind; for static variables, on program termination), and at this time (or later, depending on implementation) memory is deallocated, but no finalization is done in general. However, when an object's lifetime is tied to a variable's lifetime, the end of the variable's lifetime causes finalization of the object; this is a standard paradigm in C++.
Together these yield four implementation-level steps:
:allocation, initialization, finalization, deallocation
These steps may be done automatically by the language runtime, interpreter, or virtual machine, or may be manually specified by the programmer in a
subroutine
In computer programming, a function or subroutine is a sequence of program instructions that performs a specific task, packaged as a unit. This unit can then be used in programs wherever that particular task should be performed.
Functions may ...
, concretely via methods – the frequency of this varies significantly between steps and languages. Initialization is very commonly programmer-specified in
class-based languages, while in strict prototype-based languages initialization is automatically done by copying. Finalization is also very common in languages with deterministic destruction, notably C++, but much less common in garbage-collected languages. Allocation is more rarely specified, and deallocation generally cannot be specified.
Status during creation and destruction
An important subtlety is the status of an object ''during'' creation or destruction, and handling cases where errors occur or exceptions are raised, such as if creation or destruction fail. Strictly speaking, an object's lifetime begins when allocation completes and ends when deallocation starts. Thus during initialization and finalization an object is alive, but may not be in a consistent state – ensuring
class invariant
In computer programming, specifically object-oriented programming, a class invariant (or type invariant) is an invariant used for constraining objects of a class. Methods of the class should preserve the invariant. The class invariant constrain ...
s is a key part of initialization – and the period from when initialization completes to when finalization starts is when the object is both alive and expected to be in a consistent state.
If creation or destruction fail, error reporting (often by raising an exception) can be complicated: the object or related objects may be in an inconsistent state, and in the case of destruction – which generally happens implicitly, and thus in an unspecified environment – it may be difficult to handle errors. The opposite issue – incoming exceptions, not outgoing exceptions – is whether creation or destruction should behave differently if they occur during exception handling, when different behavior may be desired.
Another subtlety is ''when'' creation and destruction happen for
static variable
In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is ...
s, whose lifespan coincides with the run time of the program – do creation and destruction happen ''during'' regular program execution, or in special phases before and after regular execution – and how objects are destroyed at program termination, when the program may not be in a usual or consistent state. This is particularly an issue for garbage-collected languages, as they may have a lot of garbage at program termination.
Class-based programming
In class-based programming, object creation is also known as ''instantiation'' (creating an ''instance'' of a ''class''), and creation and destruction can be controlled via methods known as a ''
constructor'' and ''
destructor,'' or an ''initializer'' and ''
finalizer.'' Creation and destruction are thus also known as ''construction'' and ''destruction,'' and when these methods are called an object is said to be ''constructed'' or ''destructed'' (not "destroyed") – respectively, ''initialized'' or ''finalized'' when those methods are called.
The relationship between these methods can be complicated, and a language may have both constructors and initializers (like Python), or both destructors and finalizers (like
C++/CLI
C++/CLI is a variant of the C++ programming language, modified for Common Language Infrastructure. It has been part of Visual Studio 2005 and later, and provides interoperability with other .NET languages such as C#. Microsoft created C++/CLI ...
), or the terms "destructor" and "finalizer" may refer to language-level construct versus implementation (as in C# versus CLI).
A key distinction is that constructors are class methods, as there is no object (class instance) available until the object is created, but the other methods (destructors, initializers, and finalizers) are instance methods, as an object has been created. Further, constructors and initializers may take arguments, while destructors and finalizers generally do not, as they are usually called implicitly.
In common usage, a constructor is a method directly called explicitly by user code to create an object, while "destructor" is the subroutine called (usually implicitly, but sometimes explicitly) on object destruction in languages with deterministic object lifetimes – the archetype is C++ – and "finalizer" is the subroutine called implicitly by the garbage collector on object destruction in languages with non-deterministic object lifetime – the archetype is Java.
The steps during finalization vary significantly depending on memory management: in manual memory management (as in C++, or manual reference counting), references need to be explicitly destroyed by the programmer (references cleared, reference counts decremented); in automatic reference counting, this also happens during finalization, but is automated (as in Python, when it occurs after programmer-specified finalizers have been called); and in tracing garbage collection this is not necessary. Thus in automatic reference counting, programmer-specified finalizers are often short or absent, but significant work may still be done, while in tracing garbage collectors finalization is often unnecessary.
Resource management
In languages where objects have deterministic lifetimes, object lifetime may be used for piggybacking
resource management
In organizational studies, resource management is the efficient and effective development of an organization's resources when they are needed. Such resources may include the financial resources, inventory, human skills, production resources, or i ...
: this is called the
Resource Acquisition Is Initialization (RAII) idiom: resources are acquired during initialization, and released during finalization. In languages where objects have non-deterministic lifetimes, notably due to garbage collection, the management of memory is generally kept separate from management of other resources.
Object creation
In typical case, the process is as follows:
* calculate the size of an object – the size is mostly the same as that of the
class
Class or The Class may refer to:
Common uses not otherwise categorized
* Class (biology), a taxonomic rank
* Class (knowledge representation), a collection of individuals or objects
* Class (philosophy), an analytical concept used differentl ...
but can vary. When the object in question is not derived from a class, but from a
prototype
A prototype is an early sample, model, or release of a product built to test a concept or process. It is a term used in a variety of contexts, including semantics, design, electronics, and Software prototyping, software programming. A prototyp ...
instead, the size of an object is usually that of the internal data structure (a hash for instance) that holds its slots.
* allocation – allocating memory space with the size of an object plus the growth later, if possible to know in advance
*
binding methods – this is usually either left to the class of the object, or is resolved at
dispatch time, but nevertheless it is possible that some object models bind methods at creation time.
* calling an initializing code (namely, ''constructor'') of superclass
* calling an initializing code of class being created
Those tasks can be completed at once but are sometimes left unfinished and the order of the tasks can vary and can cause several strange behaviors. For example, in
multi-inheritance, which initializing code should be called first is a difficult question to answer. However, superclass constructors should be called before subclass constructors.
It is a complex problem to create each object as an element of an array. Some languages (e.g. C++) leave this to programmers.
Handling
exceptions in the midst of creation of an object is particularly problematic because usually the implementation of throwing exceptions relies on valid object states. For instance, there is no way to allocate a new space for an exception object when the allocation of an object failed before that due to a lack of free space on the memory. Due to this, implementations of OO languages should provide mechanisms to allow raising exceptions even when there is short supply of resources, and programmers or the type system should ensure that their code is
exception-safe. Propagating an exception is more likely to free resources than to allocate them. But in object oriented programming, object construction may fail, because constructing an object should establish the
class invariants, which are often not valid for every combination of constructor arguments. Thus, constructors can raise exceptions.
The
abstract factory pattern
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract fa ...
is a way to decouple a particular implementation of an object from code for the creation of such an object.
Creation methods
The way to create objects varies across languages. In some class-based languages, a special method known as a ''
constructor'', is responsible for validating the state of an object. Just like ordinary methods, constructors can be
overloaded in order to make it so that an object can be created with different attributes specified. Also, the constructor is the only place to set the state of
immutable object
In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created.Goetz et al. ''Java Concurrency in Practice''. Addison Wesley Professional, 2006, Section 3 ...
s. A ''
copy constructor
In class-based, object-oriented programming, a constructor (abbreviation: ctor) is a special type of subroutine called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set required ...
'' is a constructor which takes a (single) parameter of an existing object of the same type as the constructor's class, and returns a copy of the object sent as a parameter.
Other programming languages, such as
Objective-C
Objective-C is a general-purpose, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTS ...
, have class methods, which can include constructor-type methods, but are not restricted to merely instantiating objects.
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
and
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
have been criticized for not providing named constructors—a constructor must always have the same name as the class. This can be problematic if the programmer wants to provide two constructors with the same argument types, e.g., to create a point object either from the
cartesian coordinate
A Cartesian coordinate system (, ) in a plane is a coordinate system that specifies each point uniquely by a pair of numerical coordinates, which are the signed distances to the point from two fixed perpendicular oriented lines, measured in ...
s or from the
polar coordinate
In mathematics, the polar coordinate system is a two-dimensional coordinate system in which each point on a plane is determined by a distance from a reference point and an angle from a reference direction. The reference point (analogous to the ...
s, both of which would be represented by two floating point numbers. Objective-C can circumvent this problem, in that the programmer can create a Point class, with initialization methods, for example,
+newPointWithX:andY:
, and
+newPointWithR:andTheta:
. In C++, something similar can be done using static member functions.
C++ FAQ: What is the "Named Constructor Idiom"?
/ref>
A constructor can also refer to a function which is used to create a value of a tagged union
In computer science, a tagged union, also called a variant, variant record, choice type, discriminated union, disjoint union, sum type or coproduct, is a data structure used to hold a value that could take on several different, but fixed, types. O ...
, particularly in functional languages.
Object destruction
It is generally the case that after an object is used, it is removed from memory to make room for other programs or objects to take that object's place. However, if there is sufficient memory or a program has a short run time, object destruction may not occur, memory simply being deallocated at process termination. In some cases object destruction simply consists of deallocating the memory, particularly in garbage-collected languages, or if the "object" is actually a plain old data structure
In computer science and object-oriented programming, a passive data structure (PDS, also termed a plain old data structure, or plain old data, POD) is a term for a record, to contrast with objects. It is a data structure that is represented only ...
. In other cases some work is performed prior to deallocation, particularly destroying member objects (in manual memory management), or deleting references from the object to other objects to decrement reference counts (in reference counting). This may be automatic, or a special destruction method may be called on the object.
In class-based languages with deterministic object lifetime, notably C++, a '' destructor'' is a method
Method ( grc, μέθοδος, methodos) literally means a pursuit of knowledge, investigation, mode of prosecuting such inquiry, or system. In recent centuries it more often means a prescribed process for completing a task. It may refer to:
*Scien ...
called when an instance of a class is deleted, before the memory is deallocated. In C++, destructors differs from constructors in various ways: they cannot be overloaded, must have no arguments, need not maintain class invariant
In computer programming, specifically object-oriented programming, a class invariant (or type invariant) is an invariant used for constraining objects of a class. Methods of the class should preserve the invariant. The class invariant constrain ...
s, and can cause program termination if they throw exceptions.
In garbage collecting languages, objects may be destroyed when they can no longer be reached by the running code. In class-based GCed languages, the analog of destructors are '' finalizers,'' which are called before an object is garbage-collected. These differ in running at an unpredictable time and in an unpredictable order, since garbage collection is unpredictable, and are significantly less-used and less complex than C++ destructors. Example of such languages include Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
, Python
Python may refer to:
Snakes
* Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia
** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia
* Python (mythology), a mythical serpent
Computing
* Python (pro ...
, and Ruby
A ruby is a pinkish red to blood-red colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sa ...
.
Destroying an object will cause any references to the object to become invalid, and in manual memory management any existing references become dangling reference
Dangling pointers and wild pointers in computer programming are pointers that do not point to a valid object of the appropriate type. These are special cases of memory safety violations. More generally, dangling references and wild references are ...
s. In garbage collection (both tracing garbage collection and reference counting), objects are only destroyed when there are no references to them, but finalization may create new references to the object, and to prevent dangling references, object resurrection
In object-oriented programming languages with garbage collection, object resurrection is when an object comes back to life during the process of object destruction, as a side effect of a finalizer being executed.
Object resurrection causes a nu ...
occurs so the references remain valid.
Examples
C++
class Foo ;
Foo::Foo(int x)
Foo::Foo(int x, int y)
Foo::Foo(const Foo &old)
Foo::~Foo()
int main()
Java
class Foo
C#
namespace ObjectLifeTime;
class Foo
Objective-C
#import
@interface Point : Object
//These are the class methods; we have declared two constructors
+ (Point *) newWithX: (double) andY: (double);
+ (Point *) newWithR: (double) andTheta: (double);
//Instance methods
- (Point *) setFirstCoord: (double);
- (Point *) setSecondCoord: (double);
/* Since Point is a subclass of the generic Object
* class, we already gain generic allocation and initialization
* methods, +alloc and -init. For our specific constructors
* we can make these from these methods we have
* inherited.
*/
@end
@implementation Point
- (Point *) setFirstCoord: (double) new_val
- (Point *) setSecondCoord: (double) new_val
+ (Point *) newWithX: (double) x_val andY: (double) y_val
+ (Point *) newWithR: (double) r_val andTheta: (double) theta_val
@end
int
main(void)
Object Pascal
Related Languages: "Delphi", "Free Pascal", "Mac Pascal".
program Example;
type
DimensionEnum =
(
deUnassigned,
de2D,
de3D,
de4D
);
PointClass = class
private
Dimension: DimensionEnum;
public
X: Integer;
Y: Integer;
Z: Integer;
T: Integer;
public
(* prototype of constructors *)
constructor Create();
constructor Create(AX, AY: Integer);
constructor Create(AX, AY, AZ: Integer);
constructor Create(AX, AY, AZ, ATime: Integer);
constructor CreateCopy(APoint: PointClass);
(* prototype of destructors *)
destructor Destroy;
end;
constructor PointClass.Create();
begin
// implementation of a generic, non argument constructor
Self.Dimension := deUnassigned;
end;
constructor PointClass.Create(AX, AY: Integer);
begin
// implementation of a, 2 argument constructor
Self.X := AX;
Y := AY;
Self.Dimension := de2D;
end;
constructor PointClass.Create(AX, AY, AZ: Integer);
begin
// implementation of a, 3 argument constructor
Self.X := AX;
Y := AY;
Self.X := AZ;
Self.Dimension := de3D;
end;
constructor PointClass.Create(AX, AY, AZ, ATime: Integer);
begin
// implementation of a, 4 argument constructor
Self.X := AX;
Y := AY;
Self.X := AZ;
T := ATime;
Self.Dimension := de4D;
end;
constructor PointClass.CreateCopy(APoint: PointClass);
begin
// implementation of a, "copy" constructor
APoint.X := AX;
APoint.Y := AY;
APoint.X := AZ;
APoint.T := ATime;
Self.Dimension := de4D;
end;
destructor PointClass.PointClass.Destroy;
begin
// implementation of a generic, non argument destructor
Self.Dimension := deUnAssigned;
end;
var
(* variable for static allocation *)
S: PointClass;
(* variable for dynamic allocation *)
D: ^PointClass;
begin (* of program *)
(* object lifeline with static allocation *)
S.Create(5, 7);
(* do something with "S" *)
S.Destroy;
(* object lifeline with dynamic allocation *)
D = new PointClass, Create(5, 7);
(* do something with "D" *)
dispose D, Destroy;
end. (* of program *)
Python
class Socket:
def __init__(self, remote_host: str) -> None:
# connect to remote host
def send(self):
# Send data
def recv(self):
# Receive data
def close(self):
# close the socket
def __del__(self):
# __del__ magic function called when the object's reference count equals zero
self.close()
def f():
socket = Socket("example.com")
socket.send("test")
return socket.recv()
Socket will be closed at the next garbage collection round after "f" function runs and returns, as all references to it have been lost.
See also
* Resource Acquisition Is Initialization (RAII), an approach to managing resources by tying them to object lifetime
Notes
References
{{DEFAULTSORT:Object Lifetime
Object (computer science)
he:Copy constructor
pl:Konstruktor (programowanie obiektowe)
sl:Konstruktor