Last modified June 5, 2026
The FreeBasic Destructor keyword defines a special member function
that is automatically called when an object is destroyed. Destructors are
essential for proper resource cleanup in user-defined types.
In FreeBasic, a Destructor is a special method of a UDT (User
Defined Type) that executes when the object goes out of scope or is explicitly
deleted. Unlike C++, FreeBASIC destructors do not use a tilde prefix; they are
defined with the Destructor typename() syntax.
Destructors cannot take parameters or return values. Their primary purpose is to release resources like memory, file handles, or network connections that the object may have acquired during its lifetime.
Object-oriented features such as user-defined Constructors and Destructors
are only supported in the default dialect (-lang fb).
This example shows a basic UDT with a constructor and destructor.
Type Resource Public: Declare Constructor() Declare Destructor() Private: id As Integer End Type Constructor Resource() Print "Resource acquired" id = 42 End Constructor Destructor Resource() Print "Resource released for id "; id End Destructor Scope Dim res As Resource End Scope Print "After scope"
Here we define a Resource type with constructor and destructor.
When the object is created, the constructor runs. When it goes out of scope,
the destructor automatically executes. This ensures proper cleanup.
Destructors are particularly useful for managing dynamically allocated memory.
Type Buffer Public: Declare Constructor(size As Integer) Declare Destructor() Declare Property Data() As Byte Ptr Private: buffer As Byte Ptr bufSize As Integer End Type Constructor Buffer(size As Integer) buffer = Allocate(size) bufSize = size Print "Allocated "; size; " bytes" End Constructor Destructor Buffer() If buffer Then Deallocate(buffer) Print "Freed "; bufSize; " bytes" End If End Destructor Property Buffer.Data() As Byte Ptr Return buffer End Property Scope Dim buf As Buffer = Buffer(1024) ' Use the buffer... End Scope
This Buffer type manages dynamic memory allocation. The constructor
allocates memory, while the destructor ensures it is freed when the object
leaves scope. This prevents memory leaks if the programmer forgets to
deallocate manually.
Destructors are automatically called for each element when an array of objects is destroyed.
Type Item Public: Declare Constructor() ' required when declaring fixed-size arrays Declare Constructor(index As Integer) Declare Destructor() Private: itemIndex As Integer End Type Constructor Item() itemIndex = 0 Print "Item default created" End Constructor Constructor Item(index As Integer) itemIndex = index Print "Item "; index; " created" End Constructor Destructor Item() Print "Item "; itemIndex; " destroyed" End Destructor Scope Dim items(1 To 5) As Item For i As Integer = 1 To 5 items(i) = Item(i) Next End Scope
In FreeBasic, when any constructor is declared for a UDT, a matching default
(parameterless) constructor must also be provided in order to declare
fixed-size arrays of that type. When the array items goes out of
scope, destructors are called for elements in reverse order of construction.
The assignments in the loop also destroy temporaries immediately.
Destructors are called in reverse order of construction in an inheritance
hierarchy. For the base class destructor to be invoked correctly
through a base-class pointer (polymorphic destruction), the destructor in
the base type must be declared Virtual and the derived type must
Extends Object.
Type MyBase Extends Object Public: Declare Constructor() Declare Virtual Destructor() End Type Constructor MyBase() Print "Base constructor" End Constructor Destructor MyBase() Print "Base destructor" End Destructor Type MyDerived Extends MyBase Public: Declare Constructor() Declare Destructor() Override End Type Constructor MyDerived() Print "Derived constructor" End Constructor Destructor MyDerived() Print "Derived destructor" End Destructor Scope Dim obj As MyDerived End Scope
For a plain stack object, the derived destructor still runs before the base
destructor even without Virtual (static type). Declare the base
destructor Virtual to ensure the correct destructor is called
when an object is deleted through a base-class pointer.
Destructors can be explicitly called using the Delete operator
for dynamically allocated objects.
Type ManagedResource Public: Declare Constructor() Declare Destructor() Private: id As Integer End Type Constructor ManagedResource() id = 1 Print "Resource created" End Constructor Destructor ManagedResource() Print "Resource destroyed" End Destructor Dim res As ManagedResource Ptr = New ManagedResource ' Use the resource... Delete res Print "After deletion"
Here we manually control the object's lifetime. The New operator
creates the object, and Delete explicitly calls the destructor.
This is useful for objects with dynamic storage duration.
When a runtime error is raised using the Error statement,
execution jumps to an error handler established with On Error Goto
(if any). Local objects' destructors execute as their stack frames unwind during
error recovery, but FreeBASIC does not provide .NET/Java-style structured
exception handling with Try/Catch blocks.
Type SafeResource Public: Declare Constructor() Declare Destructor() Private: n As Integer End Type Constructor SafeResource() n = 42 Print "SafeResource #"; n; " created" End Constructor Destructor SafeResource() Print "SafeResource #"; n; " destroyed" End Destructor Sub RiskyOperation() Dim res As SafeResource Print "About to raise runtime error" Error 999 Print "This line is not reached" End Sub On Error Goto handler RiskyOperation() Print "No error path" End handler: Print "In error handler, Err = "; Err
Note that when a runtime error is raised with Error, the local
object's destructor is not guaranteed to run before the
On Error Goto handler takes control — the stack frame may not be
fully unwound. Additionally, Err is typically zero inside the
handler because the runtime clears the error status once control transfers.
FreeBASIC does not perform C++-style RAII stack unwinding on runtime errors.
Rely on destructors only for normal scope exits and Delete, not
as a safety net for Error-based control flow.
Destructors can ensure files are properly closed even if errors occur.
Type FileWrapper
Public:
Declare Constructor(fileName As String)
Declare Destructor()
Declare Function ReadLine() As String
Private:
fileNum As Integer
End Type
Constructor FileWrapper(fileName As String)
fileNum = FreeFile()
If Open(fileName For Input As #fileNum) Then
Print "Failed to open file"
fileNum = 0
Else
Print "File opened successfully"
End If
End Constructor
Destructor FileWrapper()
If fileNum Then
Close #fileNum
Print "File closed"
End If
End Destructor
Function FileWrapper.ReadLine() As String
Dim Result As String
If fileNum = 0 Then Return ""
Line Input #fileNum, Result
Return Result
End Function
Scope
Dim file As FileWrapper = FileWrapper("test.txt")
Print "First line: "; file.ReadLine()
End Scope
The FileWrapper type manages file resources safely using RAII.
The constructor opens the file, and the destructor ensures it is closed when
the wrapper leaves scope. This pattern avoids resource leaks even when
execution exits via Return or an early exit from a scope block.
Error-based control flow; they are not guaranteed to run.Virtual (and the type Extends Object) when you delete derived objects through a base-class pointer.
This tutorial covered the FreeBasic Destructor keyword with practical
examples showing its usage for proper resource management and cleanup.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all FreeBasic Tutorials.