ZetCode

FreeBasic Destructor Keyword

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.

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. 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).

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 is freed when the object leaves scope. This prevents memory leaks if the programmer forgets to deallocate manually.

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() ' 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.

Destructor with Inheritance

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.

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

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

Destructor and Runtime Errors

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.

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

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

Best Practices

  • RAII: Use destructors to implement Resource Acquisition Is Initialization.
  • Cleanup: Always release resources in destructors that were acquired in constructors.
  • Order: Remember destructors are called in reverse order of construction.
  • Errors: Do not rely on destructors for cleanup during Error-based control flow; they are not guaranteed to run.
  • Virtual: Declare base class destructors 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.

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.

AltStyle によって変換されたページ (->オリジナル) /