[updated topic] member function ptr

General FreeBASIC programming questions.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

Your Type template is wrong because it induces an infinite loop at instance construction:
- the 'constructor(...)' calls 'values(...)',
- and 'values(...)' calls 'type(...)', therefore the 'constructor(...)'.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: [updated topic] member function ptr

Post by dafhi »

my bad. thought it would just fill in the values.

updated.
Last edited by dafhi on Nov 29, 2019 10:29, edited 1 time in total.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

dafhi wrote:my bad. thought it would just fill in the values
Only when no constructor is defined.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

In your last code 'flo()' is not defined.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

Otherwise your last code modified to hack the vtable:

Code: Select all

  #define sng         as single
  #define decl        declare
  #define uint        as uinteger
 
 
  type func_vars extends object
   
    decl constructor      ( sng, sng, sng, sng = 1, as string = "tri" )
   
    sng                   clip_hi
    sng                   clip_lo
    sng                   off_y
    sng                   amp
   
    decl function wave ( sng ) sng
   
   private:
    decl virtual function tr( sng ) sng
    decl virtual function sw( sng ) sng
    decl         sub      values( sng, sng, sng, sng, uint )
    as function ( byref as func_vars, sng ) sng  pwave
  End Type
 
  constructor func_vars( lo sng, hi sng, off sng, amp sng, wave_name as string )
    values lo,hi,off,amp*2, 0
    if lcase( left(wave_name,3) ) <> "tri" then values lo,hi,off,amp*2, 1
  End constructor
 
  sub func_vars.values( lo sng, hi sng, off sng, _amp sng, virtual_nb uint )
    clip_hi = hi
    clip_lo = lo
    off_y = off
    amp = _amp
    pwave = Cptr(Any Ptr Ptr Ptr, @This)[0][virtual_nb]
  End Sub
  
  function func_vars.wave ( s sng ) sng
    return this.pwave(this, s)
  end function

  function func_vars.tr( i sng ) sng
   
    '' triangle:  [range -.25 to .25]
    i = abs(i - flo(i) - .5) * amp + off_y  '' Stonemonkey's formula
   
    return i + _
      ( i - clip_hi ) * ( i > clip_hi ) + _
      ( i - clip_lo ) * ( i < clip_lo )
  End function
 
  function func_vars.sw( i sng ) sng
   
    '' sawtooth:  [range -.5 to .5]
    i = (i - flo(i) - .5) * amp + off_y
   
    return i + _
      ( i - clip_hi ) * ( i > clip_hi ) + _
      ( i - clip_lo ) * ( i < clip_lo )
  End function
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: [updated topic] member function ptr

Post by dafhi »

polymorph compiles. i assume it will run faster

[update: members to protected]
[update: renamed values() => write()]

Code: Select all

  ' faster than int()  http://www.freebasic.net/forum/viewtopic.php?p=118633
  #define flo(x)    (((x)*2.0-0.5)shr 1)
  #define sng         as single
  #define decl        declare


  type func_vars extends object
    decl constructor
    decl constructor      ( sng, sng, sng, sng = 1, as string = "tri" )
   
    decl virtual function wave( sng ) sng
   
   private:
    declare sub           write( sng, sng, sng, sng )
   
   protected:
    sng                   clip_hi
    sng                   clip_lo
    sng                   off_y
    sng                   amp
  End Type
 
  constructor func_vars()
  end constructor
 
  function func_vars.wave( i sng ) sng
    return -1/0
  End Function
 
 
  '' polymorphism emulation (?)  courtesy of fxm
  type func_tr extends func_vars
    decl virtual function wave( sng ) sng
  End Type
 
  function func_tr.wave( i sng ) sng
   
    '' triangle:  [range -.25 to .25]
    i = abs(i - flo(i) - .5) * amp + off_y  '' Stonemonkey's formula
   
    return i + _
      ( i - clip_hi ) * ( i > clip_hi ) + _
      ( i - clip_lo ) * ( i < clip_lo )
  End function
 
 
  type func_sw extends func_vars
    decl virtual function wave( sng ) sng
  End Type
 
  function func_sw.wave( i sng ) sng
   
    '' sawtooth:  [range -.5 to .5]
    i = (i - flo(i) - .5) * amp + off_y
   
    return i + _
      ( i - clip_hi ) * ( i > clip_hi ) + _
      ( i - clip_lo ) * ( i < clip_lo )
  End function
 
 
  '' back to regularly scheduled programming
  constructor func_vars( lo sng, hi sng, off sng, amp sng, wave_name as string )
    #define polymorph_hack(fname) _
      Cptr(any ptr ptr, @this)[0] = Cptr(any ptr ptr, @fname())[0]
   
    select case lcase( left(wave_name,3) )
    case "saw"
      write lo,hi,off,amp:  polymorph_hack(func_sw)
    case else
      write lo,hi,off,amp*2:  polymorph_hack(func_tr)
    End Select
  End constructor
 
  sub func_vars.write( lo sng, hi sng, off sng, _amp sng )
    clip_hi = hi
    clip_lo = lo
    off_y = off
    amp = _amp
  End Sub
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

Okay.
Yes, it's faster (because of its principle).

The return value of 'func_vars.wave (...)' is irrelevant because the function is never called (when using the non-default constructor)
In my previous example, I chose 'return -1/0' just to remember the 2 possible returned values, which were '-1' / '0'.
Here, we can replace it for example by simply 'return i' (pass function)
This function can not be replaced by an 'abstract' function (without function body), because the instance is initially constructed (by its declaration) as a 'func_vars' object.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: [updated topic] member function ptr

Post by dafhi »

fxm wrote:In my previous example, I chose 'return -1/0' just to remember the 2 possible returned values, which were '-1' / '0'.
Thought you were creating an uninitialized 'NaN' condition :)
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

Between 0/-1 and -1/0, I chose the second expression only for the amusement (returning the '-1.#INF' value).
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

Important restriction:
As commented out in my example, I repeat that this hacking by down-casting the run-time type of an object only works for derived types without data members (having only procedure members and/or static data members). Otherwise, the override derived procedures could attempt to access data members in its type for which no memory was allocated during the initial construction of the object.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: [updated topic] member function ptr

Post by dafhi »

this is more clear to me

Code: Select all

type mytypeaa extends mytype  '' must not contain new members
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

Yes, but more restrictive than necessary.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: [updated topic] member function ptr

Post by dafhi »

how about

Code: Select all

'must not contain new data members
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [updated topic] member function ptr

Post by fxm »

I prefer mine:

Code: Select all

type mytypeaa extends mytype  '' must contain only procedure members (no data member)
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: [updated topic] member function ptr

Post by dafhi »

thanks for your help. Had to make a method for post-construction function re-assignment. Everything's working perfectly! =)
Post Reply