Deleteing pointer of the extended class

General FreeBASIC programming questions.
Post Reply
Isenbeck
Posts: 12
Joined: Dec 24, 2006 19:33

Deleteing pointer of the extended class

Post by Isenbeck »

The example code below will compile without error.
It contains the base class Shape that two other classes will extend. Those two classes are Rectangle And Oval.
Those two classes have a different number of fields and therefore have different sizes.

After that, the pointer to the Shape class called "obj" is declared.

Code: Select all

Dim obj As Shape Ptr
Later in the code, the user can select which type of object to assign to the "obj".
In the first case, the object of Rectangle type will be created and assigned to the "obj" pointer of a Shape type.
In the second case, the object of Ovaltype will be created and assigned to the "obj" pointer of a Shape type
The compiler will not complain.

Code: Select all

k = Inkey()

Select Case k
    Case "r"
        obj = New Rectangle
    Case "o"
        obj = New Oval
End Select
And finally, the "obj" is deleted:

Code: Select all

Delete obj
The question here is...
Will the Delete statement correctly destroy data and free memory considering that those two objects are of different sizes?

EXAMPLE CODE

Code: Select all

' Base class
Type Shape Extends Object
    Declare Abstract Sub DrawShape()    
End Type


' First shape
Type Rectangle Extends Shape
    r1 As Single
    Declare Sub DrawShape()
End Type

Sub Rectangle.DrawShape()
    ' Some code here
End Sub


' Second shape
Type Oval Extends Shape
    o1 As Single
    o2 As Single
    Declare Sub DrawShape()
End Type

Sub Oval.DrawShape()
    ' Some code here
End Sub


' MAIN PROGRAM
Dim obj As Shape Ptr
Dim k As String*1

k = Inkey()

Select Case k
    Case "r"
        obj = New Rectangle
    Case "o"
        obj = New Oval
End Select
    
Delete obj

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

Re: Deleteing pointer of the extended class

Post by fxm »

In general:
  • Destruction of the proper derived object from a base typed pointer (polymorphism calling the proper destructor) requires defining virtual destructors (even with empty body) in the base type and derived types:

    Code: Select all

    ' Base class
    Type Shape Extends Object
        Declare Abstract Sub DrawShape() 
        Declare Virtual Destructor()
    End Type
    
    Destructor Shape()
    End Destructor
    
    ' First shape
    Type Rectangle Extends Shape
        r1 As Single
        Declare Virtual Sub DrawShape()
        Declare Virtual Destructor()
    End Type
    
    Sub Rectangle.DrawShape()
        ' Some code here
    End Sub
    
    Destructor Rectangle()
    End Destructor
    
    ' Second shape
    Type Oval Extends Shape
        o1 As Single
        o2 As Single
        Declare Virtual Sub DrawShape()
        Declare Virtual Destructor()
    End Type
    
    Sub Oval.DrawShape()
        ' Some code here
    End Sub
    
    Destructor Oval()
    End Destructor
    
    ' MAIN PROGRAM
    Dim obj As Shape Ptr
    Dim k As String*1
    
    k = Inkey()
    
    Select Case k
        Case "r"
            obj = New Rectangle
        Case "o"
            obj = New Oval
    End Select
        
    Delete obj
    
    End
    
    Note 1: A destructor cannot be 'Abstract', even in the base type.
    Note 2: The 'Virtual' qualifier in the lowest level derived types is not required but recommended (ready to add yet another level of derived types).

But in your particular case:
  • Each derived type requires no special destruction (because no destructors initially, and only simple numeric variable members), so only allocated memory needs to be deallocated.
    Therefore, only the pointer value is needed to deallocate the correct number of allocated bytes, regardless of the pointer type (base or derived type pointer).

    Note:
    This would not be the case if one of the derived types contained for example a (var-len) string.
Last edited by fxm on Nov 20, 2022 16:18, edited 4 times in total.
Reason: Update.
Isenbeck
Posts: 12
Joined: Dec 24, 2006 19:33

Re: Deleteing pointer of the extended class

Post by Isenbeck »

Thank you!
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Deleteing pointer of the extended class

Post by fxm »

I just updated my post.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Deleteing pointer of the extended class

Post by dodicat »

I don't like these hypothetical situations.
Get some juice into it.

Code: Select all

' Base class
Type Shape Extends Object
    Declare Abstract Sub DrawShape()    
End Type

Type Point
    As Single x,y
End Type

' First shape
Type Rectangle Extends Shape
    Private:
    As Long x,y 
    As Long rx,ry
    As Long angle
    As Ulong fillcol
    As Ulong col
    As Long paintflag
    As Point r(1 To 4)
    As Point centre
    Public:
    Declare Constructor(xx As Long,yy As Long,rxx As Long,ryy As Long,ang As Long,fill As Ulong,clr As Ulong,pf As Long)
    Declare Sub rectangle()
    Declare Sub DrawShape()
End Type

Constructor Rectangle(xx As Long,yy As Long,rxx As Long,ryy As Long,ang As Long,fill As Ulong,clr As Ulong,pf As Long)
x=xx:y=yy:rx=rxx:ry=ryy:angle=ang:fillcol=fill:col=clr:paintflag=pf
End Constructor

Sub Rectangle.rectangle
    Print "rectangle"
    #macro rotate(pivot,p,a,d)
    Type<Point>(d*(Cos(a*.0174533)*(p.x-pivot.x)-Sin(a*.0174533)*(p.y-pivot.y)) +pivot.x,_
    d*(Sin(a*.0174533)*(p.x-pivot.x)+Cos(a*.0174533)*(p.y-pivot.y)) +pivot.y)
    #endmacro
    
    Dim As Point p(1 To 4)={(x,y),(x+rx,y),(x+rx,y+ry),(x,y+ry)}
    centre=Type(x+rx/2,y+ry/2)
    For n As Long=1 To 4
        r(n)=rotate(centre,p(n),angle,1)
    Next n
End Sub

Sub Rectangle.DrawShape()
    rectangle
    Line(r(1).x,r(1).y)-(r(2).x,r(2).y),col
    Line(r(2).x,r(2).y)-(r(3).x,r(3).y),col
    Line(r(3).x,r(3).y)-(r(4).x,r(4).y),col
    Line (r(4).x,r(4).y)-(r(1).x,r(1).y),col
    If paintflag Then Paint(centre.x,centre.y),fillcol,col
End Sub


' Second shape
Type Oval Extends Shape
    Private:
    As Long x,y
    As Long rx,ry
    As Ulong angle
    As Ulong fillcol
    As Ulong col
    As Ulong paintflag
    Public:
    Declare Constructor(As Long,As Long,As Long,As Long,As Ulong,As Ulong,As Ulong,As Ulong)
    Declare Function oval() As String
    Declare Sub DrawShape()
End Type

Constructor oval(xx As Long,yy As Long,rxx As Long,ryy As Long,ang As Ulong, col1 As Ulong,pf As Ulong,fill As Ulong)
x=xx:y=yy:rx=rxx:ry=ryy:angle=ang:col=col1:paintflag=pf:fillcol=fill
End Constructor

Function oval.oval() As String
    Print "oval"
    Dim As String s="Ta" &angle &"Bm" &x &"," &y:s+="Bm+" &rx &"," & 0:s+="C" &col
    Dim As Single pi2=8*Atn(1)
    Dim As Long lx,ly
    For z As Single=0 To pi2*1.1 Step pi2/60 '60 steps
        If z>pi2 Then Exit For
        Dim As Long xpos=rx*Cos(z)
        Dim As Long ypos=ry*Sin(z)
        If z<>0 Then s+="M+" &(xpos-lx) &"," &(ypos-ly)
        lx=xpos:ly=ypos
    Next z
    If paintflag Then s+="BM" &x &"," &y &"P" & fillcol &"," & col
    Return s
End Function

Sub Oval.DrawShape()
    Draw oval
End Sub


' MAIN PROGRAM
Screen 20
Dim obj As Shape Ptr
Dim As Long a

Do
    a+=1
    Screenlock
    Cls
    obj = New Rectangle(600,300,250,100,a,5,3,1)
    obj->drawshape
    Delete obj
    obj = New Oval(200,300,150,120,a,4,3,1)
    obj->drawshape
    Delete obj
    Screenunlock
    Sleep 5
Loop Until Inkey=Chr(27)
Sleep  


 
Last edited by dodicat on Nov 20, 2022 17:27, edited 1 time in total.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Deleteing pointer of the extended class

Post by fxm »

Line 76, '&0' inside a concatenation expression is misinterpreted by the parser of fbc 1.10.0 ('&0' is now an octal literal)
To be replaced for example with '& 0'.

Due to changelog.txt (Version 1.10.0):
- sf.net #455: fbc: Allow &nnn... octal literals in source (like VALINT and friends)

@Jeff,
Is this change really useful ?
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Deleteing pointer of the extended class

Post by dodicat »

I see what you mean, I tested on the official version.
I don't have the changelog.txt for 1.10.0
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Deleteing pointer of the extended class

Post by fxm »

dodicat wrote: Nov 20, 2022 17:26 I don't have the changelog.txt for 1.10.0
https://github.com/freebasic/fbc
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Deleteing pointer of the extended class

Post by dodicat »

Thanks.
I am far too lazy to compile the compiler these days.
I use SARG's binary fbc64_latest.exe
SARG
Posts: 1757
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Deleteing pointer of the extended class

Post by SARG »

Next time I update (lastest exe) I'll add the changelog.txt in the zip file. :D
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Deleteing pointer of the extended class

Post by dodicat »

Thanks SARG.
A little experiment, send Run time Type information (rtti) in a static lib file, to be used in another program.
shapes.bas

Code: Select all

' shapes.bas
#cmdline "-lib"
Type Shape Extends Object
    Declare Abstract Sub DrawShape() 
    Declare abstract Sub Moveshape(As Long,As Long,As Long,Byref As Long=0,Byref As Long=0,Byref As Long=0)
End Type

Type Point
    As Single x,y
End Type

' First shape
Type Rectangle Extends Shape
    Private:
    As Long x,y 
    As Long rx,ry
    As Long angle
    As Ulong fillcol
    As Ulong col
    As Long paintflag
    As Point r(1 To 4)
    As Point centre
    Public:
    Declare Constructor(xx As Long,yy As Long,rxx As Long,ryy As Long,ang As Long,fill As Ulong,clr As Ulong,pf As Long)
    Declare Sub rectangle()
    Declare Sub DrawShape()
    Declare Sub moveshape(As Long,As Long,As Long,Byref As Long=0,Byref As Long=0,Byref As Long=0)
End Type

Constructor Rectangle(xx As Long,yy As Long,rxx As Long,ryy As Long,ang As Long,fill As Ulong,clr As Ulong,pf As Long)
x=xx:y=yy:rx=rxx:ry=ryy:angle=ang:fillcol=fill:col=clr:paintflag=pf
End Constructor

Sub Rectangle.rectangle
    Print "rectangle"
    #macro rotate(pivot,p,a,d)
    Type<Point>(d*(Cos(a*.0174533)*(p.x-pivot.x)-Sin(a*.0174533)*(p.y-pivot.y)) +pivot.x,_
    d*(Sin(a*.0174533)*(p.x-pivot.x)+Cos(a*.0174533)*(p.y-pivot.y)) +pivot.y)
    #endmacro
    
    Dim As Point p(1 To 4)={(x,y),(x+rx,y),(x+rx,y+ry),(x,y+ry)}
    centre=Type(x+rx/2,y+ry/2)
    For n As Long=1 To 4
        r(n)=rotate(centre,p(n),angle,1)
    Next n
End Sub

Sub Rectangle.DrawShape()
    rectangle
    Line(r(1).x,r(1).y)-(r(2).x,r(2).y),col
    Line(r(2).x,r(2).y)-(r(3).x,r(3).y),col
    Line(r(3).x,r(3).y)-(r(4).x,r(4).y),col
    Line (r(4).x,r(4).y)-(r(1).x,r(1).y),col
    If paintflag Then Paint(centre.x,centre.y),fillcol,col
End Sub

Sub rectangle.moveshape(xx As Long,yy As Long, ang As Long,Byref rx As Long=0,Byref ry As Long=0,Byref ra As Long=0)
    x+=xx:y+=yy:angle+=ang
    rx=x:ry=y:ra=ang
End Sub

' Second shape
Type Oval Extends Shape
    Private:
    As Long x,y
    As Long rx,ry
    As Ulong angle
    As Ulong fillcol
    As Ulong col
    As Ulong paintflag
    Public:
    Declare Constructor(As Long,As Long,As Long,As Long,As Ulong,As Ulong,As Ulong,As Ulong)
    Declare Function oval() As String
    Declare Sub DrawShape()
    Declare Sub moveshape(As Long,As Long,As Long,Byref As Long=0,Byref As Long=0,Byref As Long=0)
End Type

Constructor oval(xx As Long,yy As Long,rxx As Long,ryy As Long,ang As Ulong, col1 As Ulong,pf As Ulong,fill As Ulong)
x=xx:y=yy:rx=rxx:ry=ryy:angle=ang:col=col1:paintflag=pf:fillcol=fill
End Constructor

Function oval.oval() As String
    Print "oval"
    Dim As String s="Ta" &angle &"Bm" &x &"," &y:s+="Bm+" &rx &"," & 0:s+="C" &col
    Dim As Single pi2=8*Atn(1)
    Dim As Long lx,ly
    For z As Single=0 To pi2*1.1 Step pi2/60 '60 steps
        If z>pi2 Then Exit For
        Dim As Long xpos=rx*Cos(z)
        Dim As Long ypos=ry*Sin(z)
        If z<>0 Then s+="M+" &(xpos-lx) &"," &(ypos-ly)
        lx=xpos:ly=ypos
    Next z
    If paintflag Then s+="BM" &x &"," &y &"P" & fillcol &"," & col
    Return s
End Function

Sub Oval.DrawShape()
    Draw oval
End Sub

Sub oval.moveshape(xx As Long,yy As Long, ang As Long,Byref rx As Long=0,Byref ry As Long=0,Byref ra As Long=0)
    x+=xx:y+=yy:angle+=ang
    rx=x:ry=y:ra=ang
End Sub


' SET UP

Dim As shape Ptr objR,objO
objO = New Oval(512,300,150,120,45,4,3,1)
objR= New Rectangle(512-200,300,400,100,45,5,3,1)

Type info
    As Uinteger L(20) 'big enough to hold any field
End Type

Dim Shared As info I1,I2

For m As Long=0 To 13 '13 fields of rectangle
    i1.L(m)= Cast(Uinteger,(Cptr(Any Ptr Ptr, objR)[m])) ' if m=0 get rtti else get the fields
Next m
For m As Long=0 To 8 '8 fields of oval
    i2.L(m)= Cast(Uinteger,(Cptr(Any Ptr Ptr, objO)[m])) ' if m=0 get rtti else get the fields
Next m

Sub getrtti(Byref p1 As Any Ptr,Byref p2 As Any Ptr) ' EXTERNAL
    p1=@i1:p2=@i2
End Sub


Delete objO
Delete objR
 
and the test code

Code: Select all

#inclib "shapes"
Type Shape Extends Object
    Declare Abstract Sub DrawShape() 
    Declare abstract Sub moveshape(As Long,As Long,As Long,Byref As Long=0,Byref As Long=0,Byref As Long=0)
End Type

Declare Sub getrtti(Byref p1 As Any Ptr,Byref p2 As Any Ptr)

Dim As shape Ptr y(1 To 2)
Dim As Any Ptr ir,io ' rtti information

getrtti(ir,io)

y(1)=io  'load the passed information to y()
y(2)=ir

#macro motion(z)
Static As Long rx=1,ry=1
Static As Long xpos,ypos
If xpos>800 Or xpos<z Then rx=-rx 
If ypos>600 Or ypos<200 Then ry=-ry 
#endmacro

Screen 20
Color ,7

Do
    Screenlock
    Cls
    
    For n As Long=1 To 2
        Select Case n
        Case 1
            motion(200)
            y(n)->moveshape(rx,ry,1,xpos,ypos)
        Case 2
            motion(0)
            y(n)->moveshape(rx,ry,1,xpos,ypos) 
        End Select
        y(n)->DrawShape
    Next n
    Screenunlock
    Sleep 5
Loop Until Inkey=Chr(27)
Sleep 
Post Reply