We covered the lifetimes of objects in the lifetimes and fundamental operations chapter.
In earlier chapters, you have seen that the objects are prepared for use in the constructor, which is called
this(), and the final operations of objects are applied in the destructor, which is called
For structs and other value types, the destructor is executed at the time when the lifetime of an object ends. For classes and other reference types, it is executed by the garbage collector sometime in the future. The important distinction is that the destructor of a class object is not executed when its lifetime ends.
System resources are commonly returned back to the system in destructors. For example,
std.stdio.File returns the file resource back to the operating system in its destructor. As it is not certain when the destructor of a class object will be called, the system resources that it holds may not be returned until too late when other objects cannot get a hold of the same resource.
An example of calling destructors late
Let’s define a class to see the effects of executing class destructors late. The following constructor increments a
static counter, and the destructor decrements it. As you remember, there is only one of each static member, which is shared by all of the objects of a type. Such a counter would indicate the number of objects that are yet to be destroyed.
The following program constructs objects of a class inside a loop: