ZetCode

FreeBasic Destructor Keyword

last modified June 16, 2025

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.

Basic Definition

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. It has the same name as the type preceded by a tilde (~).

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.

Simple Destructor Example

This example shows a basic UDT with a constructor and destructor.

simple_destructor.bas
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.

Destructor with Dynamic Memory

Destructors are particularly useful for managing dynamically allocated memory.

dynamic_memory.bas
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's freed. This prevents memory leaks even if exceptions occur or the programmer forgets to deallocate.

Destructor in Array of Objects

Destructors are automatically called for each element when an array of objects is destroyed.

array_destructor.bas
Type Item
    Public:
        Declare Constructor(index As Integer)
        Declare Destructor()
    Private:
        itemIndex As Integer
End Type

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

When the array items goes out of scope, the destructor is called for each element in reverse order of construction. This demonstrates automatic cleanup of object arrays.

Destructor with Inheritance

Destructors work with inheritance, being called in the reverse order of construction.

inheritance_destructor.bas
Type Base
    Public:
        Declare Constructor()
        Declare Destructor()
End Type

Constructor Base()
    Print "Base constructor"
End Constructor

Destructor Base()
    Print "Base destructor"
End Destructor

Type Derived Extends Base
    Public:
        Declare Constructor()
        Declare Destructor()
End Type

Constructor Derived()
    Print "Derived constructor"
End Constructor

Destructor Derived()
    Print "Derived destructor"
End Destructor

Scope
    Dim obj As Derived
End Scope

This example shows destructor behavior with inheritance. When the Derived object is destroyed, the derived class destructor runs first, followed by the base class destructor. This ensures proper cleanup order.

Manual Destruction with Delete

Destructors can be explicitly called using the Delete operator for dynamically allocated objects.

manual_destructor.bas
Type ManagedResource
    Public:
        Declare Constructor()
        Declare Destructor()
End Type

Constructor ManagedResource()
    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.

Destructor with Exception Handling

Destructors are called even when exceptions occur, ensuring resource cleanup.

exception_destructor.bas
Type SafeResource
    Public:
        Declare Constructor()
        Declare Destructor()
End Type

Constructor SafeResource()
    Print "SafeResource created"
End Constructor

Destructor SafeResource()
    Print "SafeResource destroyed"
End Destructor

Sub RiskyOperation()
    Dim res As SafeResource
    Print "About to throw exception"
    Error 999  ' Simulate an exception
End Sub

Try
    RiskyOperation()
Catch
    Print "Exception caught"
End Try

This demonstrates that destructors are called during stack unwinding when exceptions occur. The SafeResource object is properly cleaned up despite the exception, showing destructors' importance for exception safety.

Destructor with File Handling

Destructors can ensure files are properly closed even if errors occur.

file_destructor.bas
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
    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. The constructor opens the file, and the destructor ensures it's closed. This pattern prevents resource leaks even if exceptions occur during file operations.

Best Practices

This tutorial covered the FreeBasic Destructor keyword with practical examples showing its usage for proper resource management and cleanup.

Author

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.