Passing datatype ? (Solved)

General FreeBASIC programming questions.
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Passing datatype ? (Solved)

Post by ppf »

Hi,
is possible in Freebasic to pass a datatype UDT to SUB/Function/etc.. ?
Explanation - I wrote 1 prototype routine for ALL reading of data from random accessed files via 1 PUT command.
Because of reading different datafileformats, I need to pass a datatype for buffer (from group of datatypes) or shared variable of that datatype.
In more words, say, program is like a game.It has 40 similar levels.
Every level reads different datafile with different dataformat.Sum of datatypes for random access read is 10.
So I need somewhere to define this parameter to be easily accessible via e.g.UDT array by index of gamelevel.
Searching in manual for "retype variable & datatype passing" had no success.
One&only interesting thing founded was "Overloading", but all examples are with base datatypes, NOT with UDTs.
Other was too complicated.Pointers etc.

Any help is appreciated, thank you.
Last edited by ppf on May 11, 2019 8:21, edited 1 time in total.
Xusinboy Bekchanov
Posts: 789
Joined: Jul 26, 2018 18:28

Re: Passing datatype ?

Post by Xusinboy Bekchanov »

ppf wrote:Hi,
is possible in Freebasic to pass a datatype UDT to SUB/Function/etc.. ?

Code: Select all

Sub MyProc(ByRef Value As MyUDT)
    
End Sub
'or
Sub MyProc(Value As MyUDT Ptr)
    
End Sub
Do you mean it?
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

If the UDT list is predefined at compile time, and if the différent UDTn have a common UDT base-type that extends the Object built-in type, we can use the Run-Time Type Information to recover the right type:

Code: Select all

Type UDT Extends Object
End Type

Type UDT1 Extends UDT
  ' user fields
End Type

Type UDT2 Extends UDT
  ' user fields
End Type

Type UDT3 Extends UDT
  ' user fields
End Type

Sub UDTtest (Byval p As UDT Ptr)
  If *p Is UDT1 Then Print "UDT1"
  If *p Is UDT2 Then Print "UDT2"
  If *p Is UDT3 Then Print "UDT3"
End Sub

Dim u1 As UDT1, u2 As UDT2, u3 As UDT3
Dim As UDT Ptr pUDT(1 To 3) = {@u3, @u1, @u2}

UDTtest(pUDT(1))
UDTtest(pUDT(2))
UDTtest(pUDT(3))

Sleep
Last edited by fxm on May 03, 2019 18:27, edited 1 time in total.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Passing datatype ?

Post by srvaldez »

this may be naive, how about overloading your procedure for the differents types?
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

I assumed that ppf wanted to pass a data-type from a predefined data-type list (for example from a data-type array).
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Passing datatype ?

Post by Tourist Trap »

fxm wrote:
Sub UDTtest (Byref p As UDT Ptr)
Not sure you meant Byref here. As far as I know, if we pass the address (ptr), then it will be more suitable to do it Byval. And if we pass the object, then Byref. Correct me if wrong of course.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

You are right.
In my draft version, I had passed a base-type reference from a base-type pointer array, by dereferencing the element of array.
I updated my code according to your remark.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Passing datatype ?

Post by Tourist Trap »

Even the best do typos ;)
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

We all need each other.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

We can even do without UDT. The Object built-in can directly be the base-type of each UDTn:

Code: Select all

Type UDT1 Extends Object
  ' user fields
End Type

Type UDT2 Extends Object
  ' user fields
End Type

Type UDT3 Extends Object
  ' user fields
End Type

Sub UDTtest (Byval p As Object Ptr)
  If *p Is UDT1 Then Print "UDT1"
  If *p Is UDT2 Then Print "UDT2"
  If *p Is UDT3 Then Print "UDT3"
End Sub

Dim u1 As UDT1, u2 As UDT2, u3 As UDT3
Dim As Object Ptr pUDT(1 To 3) = {@u3, @u1, @u2}

UDTtest(pUDT(1))
UDTtest(pUDT(2))
UDTtest(pUDT(3))

Sleep
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Re: Passing datatype ?

Post by ppf »

Hi,
I am back; was busy due unexpected crashes.Ehh, 3 days lost, program was ok, datafile value typo leads to error messages, never seen before.

Thank you all for tips.
Here is extracted short code from my program - six gamelevels + 4 Random file read/write buffers & UDTs.
to demonstrate the question..
Added fxm's way.Now compiled ok, but testprints gives wrong results.
Why ?
Seems, I am missing something there


old code

Code: Select all

#include "fbgfx.bi"
screen 19,32

'UDT for (6) game level setup
type gLevelUdt
as integer IDgl		'game level ID
as string*20 nameGL		'game level name
as string*15 dataFileNameGL		'game level data filename for RANDOM read
as string*10 glPathToDataFile		'path to game level data file
rwBuffer1 as any ptr			'buffer parameters here starts
rwBuffer2 as object ptr
buffType as integer
bufferLEN as integer
bufferSize as byte

'etc etc

end type 

'just only 4 custom datatype - UDTs for RANDOM file read(write) of user data
'type rwRFileUdtA 			my way
type rwRFileUdtA Extends Object		'fxm way
	as byte a
	'etc etc
end type 

'type rwRFileUdtB
type rwRFileUdtB Extends Object
	as ushort b
	as string*3 cs
	'etc etc
end type 

'type rwRFileUdtC
type rwRFileUdtC Extends Object
	as single a
	as ubyte c
	as integer d
	as string*8 fs
	'etc etc
end type 

'type rwRFileUdtD
type rwRFileUdtD Extends Object
	as long dw
	as single a
	as ubyte c
	as integer d
	as string*10 ws
	'etc etc
end type 

'define global buffers for reading files
dim shared rwBuffieA as rwRFileUdtA 
dim shared rwBuffieB as rwRFileUdtB
dim shared rwBuffieC as rwRFileUdtC
dim shared rwBuffieD as rwRFileUdtD

'define global variables of game level parameters
dim shared iGL as integer		'level index/counter
dim shared GLid	as integer		'level ID
dim shared GLname as string*20				'level name
dim shared GLdataFileName as string*15			'datafilename
dim shared GLpathToDataFile as string*10		'path to datafilename
'etc etc

'initializing values
dim shared gameLevelsSum as integer=6				' global - how much game levels in game
dim shared gameLevelSetup(1 to gameLevelsSum) as gLevelUdt	' global - array of each gamelevel parameter list

Dim As Object Ptr pUDT(1 To 4) = {@rwBuffieA, @rwBuffieB, @rwBuffieC, @rwBuffieD}	'fxm way

'filling a gamelevel setup array

with gameLevelSetup(1)
	.IDgl=101
	.nameGL="game Level no.1"
	.dataFileNameGL="Level1.dat"
	.glPathToDataFile="/levelData/"		
	'.rwRandomBuffer	??
	.rwBuffer1=@rwBuffieA	'??
	.rwBuffer2=@rwBuffieA	'??
	.buffType=1
	.bufferLEN=LEN(rwBuffieA)
	.bufferSize=Sizeof(rwRFileUdtA)
	'etc etc
	
end with

with gameLevelSetup(2)
	.IDgl=208
	.nameGL="game Level no.2"
	.dataFileNameGL="Level2.dat"
	.glPathToDataFile="/levelData/"		
	'.rwRandomBuffer	??
	.rwBuffer1=@rwBuffieB	'??
	.rwBuffer2=@rwBuffieB	'??
	.buffType=2
	.bufferLEN=LEN(rwBuffieB)
	.bufferSize=Sizeof(rwRFileUdtB)
	'etc etc
	
end with
'...
'etc
'...
with gameLevelSetup(6)
	.IDgl=605
	.nameGL="game Level no.6"
	.dataFileNameGL="Level6.dat"
	.glPathToDataFile="/levelData/"		
	'.rwRandomBuffer	??
	.rwBuffer1=@rwBuffieC	'??
	.rwBuffer2=@rwBuffieC	'??
	.buffType=3
	.bufferLEN=LEN(rwBuffieC)
	.bufferSize=Sizeof(rwRFileUdtC)
	'etc etc
	
end with

'random fileread routine - pass only filenumber by freefile, shared gamelevel ndex iGL and a record number to random read
Sub randomReadRecord(ByVal fileNr As integer,ByVal recN As Integer)	
	scope
/'		
		'a - using pointer
		dim bufferRW as object ptr
		'dim bufferRW as any ptr
		'dim bufferRW as rwRFileUdtA ptr

		'bufferRW=gameLevelSetup(iGL).rwBuffer2
		
		 'bufferRW= CAllocate(gameLevelSetup(iGL).bufferSize)
		 'bufferRW= CAllocate(1 * SizeOf(gameLevelSetup(iGL).rwBuffer2))
		 'bufferRW= Allocate(1 * SizeOf(gameLevelSetup(iGL).buffType))
		 bufferRW= CAllocate(1 * gameLevelSetup(iGL).bufferSize)
'/		/'
		'b - using var ??
		'var bufferRW=	?? gameLevelSetup(iGL).rwRandomBuffer	??
		'var bufferRW=0		'??
		'bufferRW=Cast(udt,z)	'??
		'Get #fileNr,recN,bufferRW
		'/
		Get #fileNr,recN,*bufferRW,1
		'next line is routine to dereferencing buffer to datatype members - os ok to build it for me
		'setGLevel(iGL,bufferRW)	'fill shared parameters - select case ONLY HERE
	? "gameLevelSetup(iGL).bufferSize =";gameLevelSetup(iGL).bufferSize					'OK results printed
	? "next line gives wrong results - why ?"
	? " bufferRW= "; bufferRW;" Sizeof(bufferRW)= ";Sizeof(bufferRW);" LEN(bufferRW)= ";LEN(bufferRW)	'wrong results printed
	deallocate (bufferRW)
	end scope
end sub	

? "Sizeof types A-D"
? Sizeof(rwRFileUdtA), Sizeof(rwRFileUdtB), Sizeof(rwRFileUdtC), Sizeof(rwRFileUdtD)      
?
? "LEN Sizeof buffies A-D"
? LEN(rwBuffieA),Sizeof(rwBuffieA)
? LEN(rwBuffieB),Sizeof(rwBuffieB)
? LEN(rwBuffieC),Sizeof(rwBuffieC)
? LEN(rwBuffieD),Sizeof(rwBuffieD)

? "gameLevelSetup(1).rwBuffer2"
? gameLevelSetup(1).rwBuffer2

'? *gameLevelSetup(1).rwBuffer2

? "pUDT(1)"
? pUDT(1)
'? *pUDT(1)
'? "Typeof(pUDT) ";Typeof(pUDT)
if *pUDT(1) is rwRFileUdtA then ? "ifff  ";Sizeof(rwBuffieA)	'	var XNy=rwBuffieB
'? "XNy ";XNy


'here test random read routine
? "randomReadRecord() test.."

iGL=1	'set gamelevel 1
? iGL;" iGL"
randomReadRecord(3,3)	'dummy values to testing buffer variable functionality
?:?
iGL=2	'set gamelevel 2
? iGL;" iGL"
randomReadRecord(4,2)
?:?
iGL=6	'set gamelevel 6
? iGL;" iGL"
randomReadRecord(1,2)

sleep
end
New version

Code: Select all

	'here is simplified shorten code from my program - six gamelevels + 3 Random file red/write buffers
#include "fbgfx.bi"
screen 20,32
 'UDT for 4 user datafile formats and parameters 
type dataFRtype		
	indexFR as integer
	notes as string
	bufferType as string
	bufferVariable as string
	bufferPointer as any Ptr
	bufferLEN as byte						
	bufferSize as byte						
end type 
 'UDT for 6 game level setup
type gLevelUdt				
	as string dataFileNameGL		'game level data filename for RANDOM read
	fileFormatParmsID as integer	'index of filetype parameters
		' etc							'the rest of gamelevel parameters
end type 
'(A-D)  just only 4 custom buffer datatype - UDTs for RANDOM file reading of user data
type rwRFileUdtA 
'type rwRFileUdtA Extends Object
	as byte a
	'etc etc
end type 
type rwRFileUdtB
'type rwRFileUdtB Extends Object
	as ushort b
	as string*3 cs
	'etc etc
end type 
type rwRFileUdtC
'type rwRFileUdtC Extends Object
	as single a
	as ubyte c
	as integer d
	as string*8 fs
	'etc etc
end type 
type rwRFileUdtD
'type rwRFileUdtD Extends Object
	as long dw
	as single a
	as ubyte c
	as integer d
	as string*10 ws
	'etc etc
end type 
 'initializing values
const gameLevelsSum as integer=6				' global - how much game levels in game
dim shared gameLevelSetup(1 to gameLevelsSum) as gLevelUdt	' global - array of each gamelevel parameter list
const bufferTypeSsum=4
dim shared fileReadParm(1 to bufferTypeSsum) as dataFRtype
dim shared ff as integer	'freefile in

'define global buffers for reading files
Static shared rwBuffieA as rwRFileUdtA 
Static shared rwBuffieB as rwRFileUdtB
Static shared rwBuffieC as rwRFileUdtC
Static shared rwBuffieD as rwRFileUdtD

'pointers to buffers
Static Shared As rwRFileUdtA Ptr pA=@rwBuffieA
Static Shared As rwRFileUdtB Ptr pB=@rwBuffieB
Static Shared As rwRFileUdtC Ptr pC=@rwBuffieC
Static Shared As rwRFileUdtD Ptr pD=@rwBuffieD

 'fill some buffer variable 
'A
rwBuffieA.a=26
'B
rwBuffieB.b=12345
rwBuffieB.cs="XYZ"
'C
rwBuffieC.a=999.5
rwBuffieC.c=99
rwBuffieC.d=321000
rwBuffieC.fs="87654321"
'D
rwBuffieD.dw=123000456
rwBuffieD.a=23.4
rwBuffieD.c=101
rwBuffieD.d=23000
rwBuffieD.ws="0123456789"

'array  of I/O  parameters 
'fill values for file format + buffer
with fileReadParm(1)
	.indexFR=1						'just info
	.notes="byte only"				'short overview
	.bufferType="rwRFileUdtA"		'just info
	.bufferVariable="rwBuffieA"		'just info
	.bufferPointer=pA				'address const
	.bufferLEN=LEN(rwBuffieA)		'lenght of variable
	.bufferSize=Sizeof(rwRFileUdtA)	'size of type
end with

with fileReadParm(2)
	.indexFR=2						'just info
	.notes="ushort s"				'short overview
	.bufferType="rwRFileUdtB"		'just info
	.bufferVariable="rwBuffieB"		'just info
	.bufferPointer=pB				'address const
	.bufferLEN=LEN(rwBuffieB)		'lenght of variable
	.bufferSize=Sizeof(rwRFileUdtB)	'size of type
end with

with fileReadParm(3)
	.indexFR=3						'just info
	.notes="single uis"				'short overview
	.bufferType="rwRFileUdtC"		'just info
	.bufferVariable="rwBuffieC"		'just info
	.bufferPointer=pC				'address const
	.bufferLEN=LEN(rwBuffieC)		'lenght of variable
	.bufferSize=Sizeof(rwRFileUdtC)	'size of type
end with

with fileReadParm(4)
	.indexFR=4						'just info
	.notes="long suis"				'short overview
	.bufferType="rwRFileUdtD"		'just info
	.bufferVariable="rwBuffieD"		'just info
	.bufferPointer=pD				'address const
	.bufferLEN=LEN(rwBuffieD)		'lenght of variable
	.bufferSize=Sizeof(rwRFileUdtD)	'size of type
end with

 'define global variables of game level parameters
dim shared iGL as integer		'level index/counter
'etc 

 'filling of gamelevel setup array
with gameLevelSetup(1)
	.dataFileNameGL="Level1.dat"
	.fileFormatParmsID=1				'array index of I/O  parameters 
		'etc etc
end with
with gameLevelSetup(2)
	.dataFileNameGL="Level2.dat"
	.fileFormatParmsID=2
		'etc etc
end with
with gameLevelSetup(3)
	.dataFileNameGL="Level3.dat"
	.fileFormatParmsID=3				'array index of I/O  parameters 
		'etc etc
end with
with gameLevelSetup(4)
	.dataFileNameGL="Level4.dat"
	.fileFormatParmsID=4
		'etc etc
end with

'etc

'show it - check default data
Sub showReadinParameters(byval i as integer)
? ,"indexFR ";fileReadParm(i).indexFR					'index in array
? ,"bufferType ";fileReadParm(i).bufferType
? ,"bufferVariable ";fileReadParm(i).bufferVariable
? ,"bufferPointer ";fileReadParm(i).bufferPointer
?
end sub

	'testin - print buffer members
sub printBufferMembers(byval id as integer)
 ? "testin - print buffer members ... buffer type id= ";id
var p=fileReadParm(id).bufferPointer
	select case id
	case 1
		? "->a "; cast(Typeof(rwBuffieA) ptr, p)->a
'		? "->a2 "; Cptr(rwRFileUdtA ptr, p)	'->a
	case 2
		? "->b "; cast(Typeof(rwBuffieB) ptr, p)->b
		? "->cs "; cast(Typeof(rwBuffieB) ptr, p)->cs
	case 3
		? "->a "; cast(Typeof(rwBuffieC) ptr, p)->a
		? "->c "; cast(Typeof(rwBuffieC) ptr, p)->c
		? "->d "; cast(Typeof(rwBuffieC) ptr, p)->d
		? "->fs "; cast(Typeof(rwBuffieC) ptr, p)->fs
	case 4
		? "->dw "; cast(Typeof(rwBuffieD) ptr, p)->dw
		? "->a "; cast(Typeof(rwBuffieD) ptr, p)->a
		? "->c "; cast(Typeof(rwBuffieD) ptr, p)->c
		? "->d "; cast(Typeof(rwBuffieD) ptr, p)->d
		? "->fs "; cast(Typeof(rwBuffieD) ptr, p)->ws
'		?
'		? "->a4 "; Cptr(rwRFileUdtD ptr, p)	'->a
	end select
	
end sub	


	'random fileread routine (second version)- pass only numer of record and index of datafileformat array
Sub randomReadRecord2(byval recN As Integer,byval id as integer)	
'Sub randomReadRecord2(byval recN As Integer,byval id as integer, pX as any pointer)	
? ".. Get"					'testin
showReadinParameters(id)				'testin
var p=fileReadParm(id).bufferPointer
? "bufferPointer= ";p

'var AA=						'here setup buffer done
'  get #ff,recN,*cast(Typeof(AA) ptr, p),1
'	printBufferMembers(id)		'testin - print buffer members

end sub	

? "Sizeof types A-D "; Sizeof(rwRFileUdtA), Sizeof(rwRFileUdtB), Sizeof(rwRFileUdtC), Sizeof(rwRFileUdtD)      
?
? "LEN   Sizeof buffies A-D   pointers pA-D"
? LEN(rwBuffieA),Sizeof(rwBuffieA),pA
? LEN(rwBuffieB),Sizeof(rwBuffieB),pB
? LEN(rwBuffieC),Sizeof(rwBuffieC),pC
? LEN(rwBuffieD),Sizeof(rwBuffieD),pD


	'simulation starts here
var aqa=1
var bbq=1

'create files
dim as integer fx(1 to 4)		'freefile
 var aqar=10					'dummy
for i as integer=1 to 4	
  fx(i)=freefile()
  aqar=fileReadParm(i).bufferSize
  open gameLevelSetup(i).dataFileNameGL for random as #fx(i) Len=aqar
next i

put #fx(1),,rwBuffieA		'create files
put #fx(2),,rwBuffieB
put #fx(3),,rwBuffieC
put #fx(4),,rwBuffieD
close

	
	'simulate flow
'select gamelevel - GUI, manual etc
iGL=1						' e.g. 1
 ? "gamelevel ";iGL;" =iGL",
	'open needed datafile
 ff=freefile()
  aqa=fileReadParm(gameLevelSetup(iGL).fileFormatParmsID).bufferSize		'just for shorter notation
  bbq=gameLevelSetup(iGL).fileFormatParmsID
  open gameLevelSetup(iGL).dataFileNameGL for random as #ff Len=aqa
	randomReadRecord2(1,bbq)
 close:?

iGL=3						' set gamelevel 6  e.g. 
 ? "gamelevel ";iGL;" =iGL",
 	'open needed datafile
 ff=freefile()
 aqa=fileReadParm(gameLevelSetup(iGL).fileFormatParmsID).bufferSize		'just for shorter notation
 bbq=gameLevelSetup(iGL).fileFormatParmsID
 open gameLevelSetup(iGL).dataFileNameGL for random as #ff Len=aqa
 	randomReadRecord2(1,bbq)
 close:?
  
iGL=4	'set gamelevel 3
? "gamelevel ";iGL;" =iGL",
 	'open needed datafile
 ff=freefile()
 aqa=fileReadParm(gameLevelSetup(iGL).fileFormatParmsID).bufferSize		'just for shorter notation
 bbq=gameLevelSetup(iGL).fileFormatParmsID
 open gameLevelSetup(iGL).dataFileNameGL for random as #ff Len=aqa
 	randomReadRecord2(1,bbq)
 close:?
 

close
? "ended, press key..."
sleep
end
Last edited by ppf on May 11, 2019 8:15, edited 1 time in total.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

In your code above, bufferRW is not declared because of the multi-line comment block.
In any cases, bufferRW must be declared as a typed pointer (<> Any Ptr, and <> object Ptr), for example as a pointer to a UDT.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Passing datatype ?

Post by Tourist Trap »

ppf wrote:

Code: Select all

'type rwRFileUdtB
type rwRFileUdtB Extends Object
	as ushort b
	as string*3 cs
	'etc etc
end type 
Hi ppf,

As far as I understand what you want to do here, with the part with GET# that requires the buffer size. I'm thinking of this:

Code: Select all

type BASEOBJECT extends OBJECT
    declare abstract function MySize() as integer
end type

type UDT1 extends BASEOBJECT
    declare function MySize() as integer
    as integer _dummy(1 to 1000)
end type
function UDT1.MySize() as integer
    #print typeOf(THIS)
    return sizeOf(THIS)
end function

dim as UDT1 uu
? sizeOf(BASEOBJECT)
? sizeOf(uu)
? uu.MySize()
You could use a BASEOBJECT that will ask your derived type to implement a function MySize() that returns the size. So even if you don't know the type of "uu", you can always do a "uu.MySize()".
Maybe it's not what you want. Anyway you still can force your UDTs to embed certain identical procedures that give information on themselves, even if you don't know anything of the variable. This way you don't have to use an external description like an enum and so on. You just have to know the name of the procedures you know being defined, and call them.
fxm
Moderator
Posts: 12108
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Passing datatype ?

Post by fxm »

To take advantage of polymorphism (with the 'MySize()' abstract method declared in the 'BASEOBJECT' base-type), you must call 'MySize()' on base-type [ptr] typed variables:

Code: Select all

type BASEOBJECT extends OBJECT
    declare abstract function MySize() as integer
end type

type UDT1 extends BASEOBJECT
    declare function MySize() as integer
    as integer _dummy(1 to 1000)
end type
function UDT1.MySize() as integer
    #print typeOf(THIS)
    return sizeOf(THIS)
end function

dim u1 as UDT1 ' , u2 as UDT2, u3 as UDT3
dim as BASEOBJECT Ptr pu(1 To 3) = {@u1} ' {@u1, @u2, @u3}
? sizeOf(BASEOBJECT)
? sizeOf(u1)
? pu(1)->MySize()
Otherwise, the 'BASEOBJECT' base-type with its abstract method is useless.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Passing datatype ?

Post by Tourist Trap »

fxm wrote:]Otherwise, the 'BASEOBJECT' base-type with its abstract method is useless.
I guess I wanted to do what you show above :)
But not totally useless to just declare the procedure abstract. If you don't implement it, you get a compilation error:

Code: Select all

error 306: UDT has unimplemented abstract methods
Post Reply