Class example questions

New to FreeBASIC? Post your questions here.
Post Reply
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Class example questions

Post by Löwenherz »

hello, I have general questions about classes For better understanding in freebasic:
a) what Is the meaning of For example "this." command -> here "this.mytext" in a Class oop example And where/when To use it?
it's a kind of a pointer?
b) when I should use operators?

If you have another example To study For me I am glad To see..

thanks in advance, löwenherz

Code: Select all

TYPE mysample
  mytext AS STRING
  DECLARE CONSTRUCTOR ()
  DECLARE CONSTRUCTOR ( a AS INTEGER )
  DECLARE CONSTRUCTOR ( a AS SINGLE  )
  DECLARE CONSTRUCTOR ( a AS STRING, b AS BYTE )
  DECLARE OPERATOR CAST () AS STRING
END TYPE

CONSTRUCTOR mysample ()
  PRINT "constructor mysample ()"
  PRINT
  THIS.mytext = "empty"
END CONSTRUCTOR

CONSTRUCTOR mysample ( a AS INTEGER )
  PRINT "constructor mysample ( a As Integer )"
  PRINT "  a = "; a
  PRINT
  THIS.mytext = STR(a)
END CONSTRUCTOR

CONSTRUCTOR mysample ( a AS SINGLE )
  PRINT "constructor mysample ( a As Single )"
  PRINT "  a = "; a
  PRINT
  THIS.mytext = STR(a)
END CONSTRUCTOR

CONSTRUCTOR mysample ( a AS STRING, b AS BYTE )
  PRINT "constructor mysample ( a As String, b As Byte )"
  PRINT "  a = "; a
  PRINT "  b = "; b
  PRINT
  THIS.mytext = a & "," & b
END CONSTRUCTOR

OPERATOR mysample.CAST () AS STRING
  RETURN THIS.mytext
END OPERATOR

PRINT "build x1"
DIM x1 AS mysample

PRINT "build x2"
DIM x2 AS mysample = 1

PRINT "build x3"
DIM x3 AS mysample = 99.9

PRINT "build x4"
DIM x4 AS mysample = mysample( "aaa", 1 )

PRINT "values:"
PRINT "  x1 = "; x1
PRINT "  x2 = "; x2
PRINT "  x3 = "; x3
PRINT "  x4 = "; x4
SLEEP
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Class example questions

Post by fxm »

When calling explicitly or implicitly any non static member procedure on a type instance, the instance is passed to the procedure but as the first hidden parameter.
(implicit call can be a constructor/destructor call induced by 'DIM' for example)
'THIS' is not the passed instance but a reference to this passed instance. So '@THIS' value is equal to the address of the passed instance.
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Class example questions

Post by fxm »

Operator overloading is a way to define the behavior of operators when used with your own custom classes. By defining special methods in your class, you can make your objects respond to standard operators in a way that makes sense for your specific use case.

Operator overloading can make your code more readable and intuitive. Instead of using verbose method calls, you can use familiar operators to perform operations on your objects. This can lead to more concise and expressive code, which can be especially useful when working with complex data structures or mathematical operations.
Imortis
Moderator
Posts: 1981
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Class example questions

Post by Imortis »

fxm wrote: Apr 07, 2025 9:17 When calling explicitly or implicitly any non static member procedure on a type instance, the instance is passed to the procedure but as the first hidden parameter.
(implicit call can be a constructor/destructor call induced by 'DIM' for example)
'THIS' is not the passed instance but a reference to this passed instance. So '@THIS' value is equal to the address of the passed instance.
While this is absolutely true, its a bit dense. I know what "this" is and does and this still confused me a bit on the first read.

An simpler way to put it, if not 100% accurate, is that "this" is used to tell the compiler you specifically want to use the members of your Type.

Code: Select all

dim shared foo as long
type bar
	foo as string
	declare constructor(_foo as string)
end type

constructor bar(_foo as string)
	this.foo = _foo 'This is specifying the member foo, which is a string, not the global foo, which is a long.
end constructor
In most cases, "this" isn't needed. For my own code, I like to use "this" because it makes the meaning clearer and makes me less likely to make a mistake.
fxm wrote: Apr 07, 2025 11:59 Operator overloading is a way to define the behavior of operators when used with your own custom classes. By defining special methods in your class, you can make your objects respond to standard operators in a way that makes sense for your specific use case.

Operator overloading can make your code more readable and intuitive. Instead of using verbose method calls, you can use familiar operators to perform operations on your objects. This can lead to more concise and expressive code, which can be especially useful when working with complex data structures or mathematical operations.
No complaints, though I will make 1 addition: Operator overloading can be very useful, but don't use it in was that would be confusing later. It is possible to make the "+" operator do something other than addition using overloading. So long as you try to keep things logical and minimal inside your operators, you should be just fine.
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Class example questions

Post by fxm »

A static member procedure can be equivalent to a non static member procedure if for the static member procedure we add a parameter corresponding to the type instance passed by reference (also named 'THIS' in the example below for better comparison):

Code: Select all

Type UDT
    Dim As Integer I
    Declare Sub Set(Byval I0 As Integer)                            '' non static member procedure
    Declare Function Get() As Integer                               '' non static member procedure
    Declare Static Sub Set(Byref This As UDT, Byval I0 As Integer)  '' static member procedure
    Declare Static Function Get(Byref This As UDT) As Integer       '' static member procedure
End Type

Sub UDT.Set(Byval I0 As Integer)  '' non static member procedure
    This.I = I0
End Sub

Function UDT.Get() As Integer  '' non static member procedure
    Return This.I
End Function

Sub UDT.Set(Byref This As UDT, Byval I0 As Integer)  '' static member procedure
    This.I = I0
End Sub

Function UDT.Get(Byref This As UDT) As Integer  '' static member procedure
    Return This.I
End Function

Dim As UDT u

u.Set(1)
Print u.Get()

UDT.Set(u, 2)
Print UDT.Get(u)
Same code for the non static and static member procedures.
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Class example questions

Post by Löwenherz »

hello fxm, imortis thanks For your declarations And feedback
look at These two examples below, how I can prevent Using "with." in my Second example For correct running?
thanks fxm for your example too.

Code: Select all

' test example with "this."
' 1)
Type vec4
	as single w,x,y,z
	Declare Constructor ()
    declare constructor ( w As Single, x as single ,  y as single ,  z as single )
end type

constructor vec4 ( w As Single, x as single,  y as single,  z as single)
    this.w = w
    this.x = x
    this.y = y
    this.z = z
end constructor

dim as vec4 p=any
p = vec4(1,2,3,4)
print p.w,p.x,p.y,p.z
sleep 

' 2) it's possible to run this example without this.wa=wa ?
type vec4a
	as Single wa,xa,ya,za ' ptr ?
	Declare Constructor ()
    declare constructor ( wa As Single, xa as single, ya as single, za as single) ' single ptr ?
end type

constructor vec4a ( wa As Single, xa as Single,  ya as Single, za as Single ) ' single ptr ?
    ' how to replace this.wa ???
    'this.wa = wa
    'this.xa = xa
    'this.ya = ya    
    'this.za = za
    
end constructor

dim as vec4a pa=any
pa = vec4a(5,6,7,8)
print pa.wa,pa.xa,pa.ya,pa.za

sleep 

Imortis
Moderator
Posts: 1981
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Class example questions

Post by Imortis »

Löwenherz wrote: Apr 07, 2025 17:34 hello fxm, imortis thanks For your declarations And feedback
look at These two examples below, how I can prevent Using "with." in my Second example For correct running?
thanks fxm for your example too.

Code: Select all

' test example with "this."
' 1)
Type vec4
	as single w,x,y,z
	Declare Constructor ()
    declare constructor ( w As Single, x as single ,  y as single ,  z as single )
end type

constructor vec4 ( w As Single, x as single,  y as single,  z as single)
    this.w = w
    this.x = x
    this.y = y
    this.z = z
end constructor

dim as vec4 p=any
p = vec4(1,2,3,4)
print p.w,p.x,p.y,p.z
sleep 

' 2) it's possible to run this example without this.wa=wa ?
type vec4a
	as Single wa,xa,ya,za ' ptr ?
	Declare Constructor ()
    declare constructor ( wa As Single, xa as single, ya as single, za as single) ' single ptr ?
end type

constructor vec4a ( wa As Single, xa as Single,  ya as Single, za as Single ) ' single ptr ?
    ' how to replace this.wa ???
    'this.wa = wa
    'this.xa = xa
    'this.ya = ya    
    'this.za = za
    
end constructor

dim as vec4a pa=any
pa = vec4a(5,6,7,8)
print pa.wa,pa.xa,pa.ya,pa.za

sleep 

Code: Select all

type vec4a
	as Single wa,xa,ya,za ' ptr ?
	Declare Constructor ()
    declare constructor ( _wa As Single, _xa as single, _ya as single, _za as single) ' single ptr ?
end type

constructor vec4a ( _wa As Single, _xa as Single,  _ya as Single, _za as Single ) ' single ptr ?
    
    wa = _wa
    xa = _xa
    ya = _ya    
    za = _za
    
end constructor

dim as vec4a pa=any
pa = vec4a(5,6,7,8)
print pa.wa,pa.xa,pa.ya,pa.za

sleep 
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Class example questions

Post by fxm »

Another variation:

Code: Select all

type vec4a
	as Single wa,xa,ya,za
	Declare Constructor ()
    declare constructor ( wa As Single, xa as single, ya as single, za as single)
end type

constructor vec4a ( wa As Single, xa as Single,  ya as Single, za as Single )
    with this
        .wa = wa
        .xa = xa
        .ya = ya    
        .za = za
    end with
end constructor

dim as vec4a pa=any
pa = vec4a(5,6,7,8)
print pa.wa,pa.xa,pa.ya,pa.za

sleep 
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Class example questions

Post by Löwenherz »

hello fxm And imortis, thanks For your examples And help. I understand more thx..
I made This Constructor Type example And I have only This little problem that
the user_right.Constructor() appears double.
Basis example I have found at Wiki pages.

Code: Select all

' class example with types, child constructor and more..
' only one little problem: user_right.Constructor() appears double
'
Type animal
  Dim As String animalName
  Protected:
    Dim As Integer serialNumber
End Type

Type doggy Extends animal
  Dim As String masterName
  Declare Sub setSerialNumber ( ByVal number As Integer )
End Type

Sub doggy.setSerialNumber ( ByVal number As Integer )
  '' This is OK. We're inside a member function of the derived type
  This.serialNumber = number
End Sub

Dim As doggy Dy

'' This is OK, animalName is public
dy.animalName = "BatmanDog"
Print dy.animalName
Print ""

'2)
Type user_right
  Public:
    Declare Property token () As String          '' 'Public' to authorize user_right token get
  Protected:
    Declare Constructor ()                       '' 'Protected' to forbid user_right object default-construction
    Declare Constructor (ByRef u As user_right)  '' 'Protected' to forbid user_right object copy-construction
    Declare Destructor ()
    Declare Property token (ByRef s As String)   '' 'Protected' to forbid user_right token set
  Private:
    Dim As String user_right_token               '' 'Private' to forbid access from outside user_right
End Type

Constructor user_right ()  '' Default-constructor
  Print "user_right.Constructor()"
End Constructor

Constructor user_right (ByRef u As user_right)  '' Protected copy-constructor
  This.user_right_token = u.user_right_token
End Constructor

Destructor user_right ()  '' define user_right Type destructor
    Print "user_right.Destructor()"
End Destructor


Property user_right.token () As String  '' Public property user_right token get
  Return This.user_right_token
End Property

Property user_right.token (ByRef s As String)  '' Protected property user_right token set
  This.user_right_token = s
End Property

' 3)
Type admin_right Extends user_right
  Public:
    Declare Property token () As String         '' 'Public' to authorize admin_right token get
    Declare Property token (ByRef s As String)  '' 'Public' to authorize admin_right token set
End Type

Property admin_right.token () As String  '' Public property admin_right token get
  Return Base.token                      '' 'Base.' to access to the base type property shadowed by this property name
End Property

Property admin_right.token (ByRef s As String)  '' Public property admin_right token set
  Base.token = s                                '' 'Base.' to access to the base type property shadowed by this property name
End Property

'------------- add new child type and constructor ------------ //
Type Child Extends user_right  '' declare the child Type
    Declare Constructor ()
    Declare Destructor ()
End Type

Constructor Child ()  '' define child Type default constructor
    Print "  Child.Constructor()"
End Constructor

Destructor Child ()  '' define child Type destructor
    Print "  Child.Destructor()"
End Destructor

Scope
    Dim As Child ch
    Print
End Scope
'------------- add new child type and constructor ------------ //

Dim As admin_right admr       '' Create an admin_right type object 'ar'
admr.token = "Loewenherz-123-456-789-0"   '' admin_right set the token for user_right
Print "'" & admr.token & "'"  '' admin_right get the user_right token
Print

Dim ByRef As user_right ur = admr  '' Create a user_right type reference 'ur' to the 'ar' instance of admin_right type
Print "'" & ur.token & "'"       '' user_right get its token

Sleep
' ends

fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Class example questions

Post by fxm »

The second 'user_right.Destructor()' is hidden from the console because the corresponding destructor is called at the end of the program (after 'Sleep').
To see it, also include the second part of the program in a [Scope...End Scope] block with 'Sleep' after 'End Scope'.
(The destructor is called when the program goes out the object scope)

Code: Select all

' class example with types, child constructor and more..
' only one little problem: user_right.Constructor() appears double
'
Type animal
  Dim As String animalName
  Protected:
    Dim As Integer serialNumber
End Type

Type doggy Extends animal
  Dim As String masterName
  Declare Sub setSerialNumber ( ByVal number As Integer )
End Type

Sub doggy.setSerialNumber ( ByVal number As Integer )
  '' This is OK. We're inside a member function of the derived type
  This.serialNumber = number
End Sub

Dim As doggy Dy

'' This is OK, animalName is public
dy.animalName = "BatmanDog"
Print dy.animalName
Print ""

'2)
Type user_right
  Public:
    Declare Property token () As String          '' 'Public' to authorize user_right token get
  Protected:
    Declare Constructor ()                       '' 'Protected' to forbid user_right object default-construction
    Declare Constructor (ByRef u As user_right)  '' 'Protected' to forbid user_right object copy-construction
    Declare Destructor ()
    Declare Property token (ByRef s As String)   '' 'Protected' to forbid user_right token set
  Private:
    Dim As String user_right_token               '' 'Private' to forbid access from outside user_right
End Type

Constructor user_right ()  '' Default-constructor
  Print "user_right.Constructor()"
End Constructor

Constructor user_right (ByRef u As user_right)  '' Protected copy-constructor
  This.user_right_token = u.user_right_token
End Constructor

Destructor user_right ()  '' define user_right Type destructor
    Print "user_right.Destructor()"
End Destructor


Property user_right.token () As String  '' Public property user_right token get
  Return This.user_right_token
End Property

Property user_right.token (ByRef s As String)  '' Protected property user_right token set
  This.user_right_token = s
End Property

' 3)
Type admin_right Extends user_right
  Public:
    Declare Property token () As String         '' 'Public' to authorize admin_right token get
    Declare Property token (ByRef s As String)  '' 'Public' to authorize admin_right token set
End Type

Property admin_right.token () As String  '' Public property admin_right token get
  Return Base.token                      '' 'Base.' to access to the base type property shadowed by this property name
End Property

Property admin_right.token (ByRef s As String)  '' Public property admin_right token set
  Base.token = s                                '' 'Base.' to access to the base type property shadowed by this property name
End Property

'------------- add new child type and constructor ------------ //
Type Child Extends user_right  '' declare the child Type
    Declare Constructor ()
    Declare Destructor ()
End Type

Constructor Child ()  '' define child Type default constructor
    Print "  Child.Constructor()"
End Constructor

Destructor Child ()  '' define child Type destructor
    Print "  Child.Destructor()"
End Destructor

Scope
    Dim As Child ch
    Print
End Scope
Print
'------------- add new child type and constructor ------------ //

Scope
    Dim As admin_right admr       '' Create an admin_right type object 'ar'
    admr.token = "Loewenherz-123-456-789-0"   '' admin_right set the token for user_right
    Print "'" & admr.token & "'"  '' admin_right get the user_right token
    Print

    Dim ByRef As user_right ur = admr  '' Create a user_right type reference 'ur' to the 'ar' instance of admin_right type
    Print "'" & ur.token & "'"       '' user_right get its token
End Scope

Sleep
' ends
Post Reply