Thread overview
callbacks/pointers to member functions
Feb 08, 2002
Patrick Down
Feb 08, 2002
Pavel Minayev
Feb 08, 2002
Patrick Down
February 08, 2002

I've been thinking about pointers to member functions.  In C++ they are very messy.  However you doo need methods of defining callbacks from one object to another.

Interfaces come close to helping in this situation.

interface ClsACallback
{
  void SomeEvent();
}

class A
{
  SetCallback(ClsACallback cb)
  {
  }
}

class B : ClsACallback
{
  A theA;

  Init()
  {
    theA = new A;

    theA.SetCallback(this);
  }

  void SomeEvent()
  {
    // Handle event
  }
}

But what about the situation where you have multible
event producers of the same type that need different
handlers?

class B
{
  A theA1;
  A theA2;
  A theA3;

  Init()
  {
    theA1 = new A;
    theA3 = new A;
    theA3 = new A;

    // How do we set up the callbacks now?

  }

  void SomeEventFromTheA1()
  {
    // Handle event from A1
  }
  void SomeEventFromTheA2()
  {
    // Handle event from A2
  }
  void SomeEventFromTheA3()
  {
    // Handle event from A3
  }
}


In C++ we might use pointers to member functions.

  theA1->SetCallback(this,B::SomeEventFromTheA1);

Or you might pass a static function.

  theA1->SetCallback(this,RedirFuncTheA1);

  // Somewhere else
  void RedirFuncTheA1(B theB)
  {
    theB->SomeEventFromTheA1();
  }

Java solves this problem with inner classes.

I have one other solution I call named vtables.
Instead of defining that a class has just one
interface by inheritance you allow multiple
implemetations of that iterface and give them
different names.


class B
{
  A theA1;
  A theA2;
  A theA3;

  Init()
  {
    theA1 = new A;
    theA3 = new A;
    theA3 = new A;

    theA1.SetCallback(clsA1CB);
    theA2.SetCallback(clsA2CB);
    theA3.SetCallback(clsA3CB);

  }

  // Create an interface ClsACallback vtable for class B
  // called clsA1CB
  ClsACallback clsA1CB
  {
    void SomeEvent()
    {
      // Handle event from A1
    }
  }

  // Create an interface ClsACallback vtable for class B
  // called clsA1CB
  ClsACallback clsA2CB
  {
    void SomeEvent()
    {
      // Handle event from A2
    }
  }

  // Create an interface ClsACallback vtable for class B
  // called clsA1CB
  ClsACallback clsA3CB
  {
    void SomeEvent()
    {
      // Handle event from A3
    }
  }
}





February 08, 2002
"Patrick Down" <pdown@austin.rr.com> wrote in message news:a3v6j9$153f$1@digitaldaemon.com...
>
>
> I've been thinking about pointers to member functions.  In C++ they are very messy.  However you doo need methods of defining callbacks from one object to another.

I've had a leeeeeeengthy discussion with Walter on
the topic already, see earlier on the newsgroup =)

> I have one other solution I call named vtables.
> Instead of defining that a class has just one
> interface by inheritance you allow multiple
> implemetations of that iterface and give them
> different names.

A very interesting idea that I also had. However, currently the way D handles casting class to interface (for details see _d_interface_vtbl() in cast.d in Phobos), two interfaces with the same classinfo - which happens in your case - cannot coexist in a single class. Well they can, but the first one will always be selected.




February 08, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in news:a40j59$1oqv$1 @digitaldaemon.com:

> "Patrick Down" <pdown@austin.rr.com> wrote in message news:a3v6j9$153f$1@digitaldaemon.com...
>>
>>
>> I've been thinking about pointers to member functions.  In C++ they are very messy.  However you doo need methods of defining callbacks from one object to another.
> 
> I've had a leeeeeeengthy discussion with Walter on
> the topic already, see earlier on the newsgroup =)
> 
>> I have one other solution I call named vtables.
>> Instead of defining that a class has just one
>> interface by inheritance you allow multiple
>> implemetations of that iterface and give them
>> different names.
> 
> A very interesting idea that I also had. However, currently the way D handles casting class to interface (for details see _d_interface_vtbl() in cast.d in Phobos), two interfaces with the same classinfo - which happens in your case - cannot coexist in a single class. Well they can, but the first one will always be selected.
> 

Yes after looking over cast.d I see why interfaces of the same type can't coexist in the interfaces list.  However it seems like you could treat named vtables as a different mechanism, more like a static class variable.