digitalmars.D.learn - pointer to member function
- Pinzo (34/34) Sep 05 2005 Hello.
- Stewart Gordon (30/52) Sep 05 2005 That's because D doesn't have pointers to members as such. It has
-
pinzo correo.nu
(30/40)
Sep 07 2005
On Mon, 05 Sep 2005 15:01:27 +0200, Stewart Gordon
... - Jarrett Billingsley (27/32) Sep 07 2005 DFL, a Windows forms library for D that emulates .NET forms, uses delega...
- Stewart Gordon (16/44) Sep 08 2005 Then don't wrap ALL functions. Wrap only the ones you're going to use
-
pinzo correo.nu
(100/106)
Sep 08 2005
On Thu, 08 Sep 2005 11:01:59 +0200, Stewart Gordon
...
Hello. I'm translating some C++ code to D, and I have found a problem with a pointer-to-member-function variable. In C++ I have the following: class Foo { void fun() {} }; { void (Foo::*pm)(); //Declare pm as pointer to member function pm = &Foo::fun; // assign .. Foo o; //Get an object (o.*pm)(); //And call the pm into it! } Now, in D, I cannot get it work: class Foo { void fun() {} } { void function() pm; pm = &Foo.fun; // Get a completely useless pointer to function .. Foo o; //What do I do with o/pm pm(); // Crashes!!! } Delegates doesn't work either, because when I get the pointer to member, I don't have the reference to de object yet. Am I losing something? Or would I have to resort to low-level tricks to workaround? -- Pinzo
Sep 05 2005
Pinzo wrote:Hello. I'm translating some C++ code to D, and I have found a problem with a pointer-to-member-function variable.That's because D doesn't have pointers to members as such. It has delegates instead. <snip>class Foo { void fun() {} } {Huh? What's this the body of?void function() pm; pm = &Foo.fun; // Get a completely useless pointer to function .. Foo o; //What do I do with o/pm pm(); // Crashes!!! } Delegates doesn't work either, because when I get the pointer to member, I don't have the reference to de object yet. Am I losing something? Or would I have to resort to low-level tricks to workaround?You could define a static wrapper. Only you'd need to wrap each function you're going to point it to. ---------- class Foo { void fun() {} static void fun(Foo f) { f.fun(); } } void functionWithNoName() { void function(Foo) pm; pm = &Foo.fun; .. Foo o = new Foo; pm(o); } ---------- Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 05 2005
On Mon, 05 Sep 2005 15:01:27 +0200, Stewart Gordon <smjg_1998 yahoo.com>= = wrote:Eh? Doesn't care, just some generic code...{Huh? What's this the body of?You could define a static wrapper. Only you'd need to wrap each =function you're going to point it to. ---------- class Foo { void fun() {} static void fun(Foo f) { f.fun(); } }8-| I'm using this to handle windows messages, I just can't have ALL = functions wrapped!!! I have been reading the ABI and got the following quite-not-portable cod= e: union Delegate_Function { void delegate() d; struct { Object o; void function() f; } } void callDF(Object o, void function() f) { Delegate_Function df; df.o =3D o; df.f =3D f; df.d(); } (Hey, it works!) It would be nice to have portable versions for this and similar code int= o = the standard library... --- Pinzo
Sep 07 2005
<pinzo correo.nu> wrote in message news:op.swq9bevjfo3y47 pinzopc2... On Mon, 05 Sep 2005 15:01:27 +0200, Stewart Gordon <smjg_1998 yahoo.com> wrote: 8-| I'm using this to handle windows messages, I just can't have ALL functions wrapped!!!DFL, a Windows forms library for D that emulates .NET forms, uses delegates for wrapping all the controls' event handlers. It has a pretty ingenious method, too. The base class Control implements a wndProc method that will do something for each message. Besides handling the message, it also calls the Control's corresponding on__ function; i.e. for WM_PAINT, it calls onPaint(). onPaint() then call's the Control's paint "event handler." EventHandler is actually a template which defines opCall(). EventHandler keeps a list of delegates which will be called when the message is sent to the control. You can add to this list with ~=. So it goes something like this: class MyForm : Form // class Form is part of DFL { private void onButton1Click(Object sender, EventArgs ea) { // do something here } private Button mButton1; this() { mButton1 = new Button; mButton1.parent = this; mButton1.click ~= &onButton1Click; } } So whenever mButton1 is clicked, the delegate will be run. Notice that the delegate isn't a member function of the Button class; it doesn't even have to be.
Sep 07 2005
pinzo correo.nu wrote: <snip>Then don't wrap ALL functions. Wrap only the ones you're going to use as window procedures or whatever.class Foo { void fun() {} static void fun(Foo f) { f.fun(); } }8-| I'm using this to handle windows messages, I just can't have ALL functions wrapped!!!I have been reading the ABI and got the following quite-not-portable code: union Delegate_Function { void delegate() d; struct { Object o; void function() f; } } void callDF(Object o, void function() f) { Delegate_Function df; df.o = o; df.f = f; df.d(); } (Hey, it works!)<snip> What do you mean by "works" exactly? How about sharing an example of code that calls this code? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 08 2005
On Thu, 08 Sep 2005 11:01:59 +0200, Stewart Gordon <smjg_1998 yahoo.com>= = wrote:=8-| I'm using this to handle windows messages, I just can't have ALL==functions wrapped!!!Then don't wrap ALL functions. Wrap only the ones you're going to use=as window procedures or whatever.The point here is that this code is a generic library, and I don't want = to = force the clients to wrap the functions before they can use them.What do you mean by "works" exactly? How about sharing an example of ==code that calls this code?Works: behaves as intended. I'll try to explain my code structure (simplified) and post a little = extract of it. The library has a class 'Wnd' that receives and handles window messages = = (WMs) through the 'onMsg' virtual member function. class Wnd { ... bool onMsg(Msg *msg) { defWindowProc(msg); return false; //means 'default processed' } } Then, the clients can create subclass of 'Wnd' (e.g.: SubWnd) and say th= at = this subclass wants to handle certain WMs. For this, in C++ I had a collection of macros = (ugh!) but in D I've created a nice mixin (I like mixins, but I really like when I can use them!). This mixin adds to the subclass a static associative array that maps WMs= = to function pointers. template DECLARE_WND_MESSAGES() { protected: alias void function(Msg*) msgFun_t; static void WND_MESSAGE(UINT msg, msgFun_t msgFun) { assert(!(msg in s_msgMap)); s_msgMap[msg] =3D msgFun; } bool onMsg(Msg *msg) { msgFun_t *msgFun =3D msg.uMsg in s_msgMap; if (msgFun) { Delegate_Function!(Msg*).call(this, *msgFun, msg); // **** = = HERE is the hack! return true; } return super.onMsg(msg); } private: static msgFun_t[UINT] s_msgMap; } Then in the definition of the subclass, I associate the WM to the functi= on = in the static constructor. class WndFoo : public Wnd { mixin DECLARE_WND_MESSAGES; static this() { WND_MESSAGE(WM_CREATE, &onCreate); } void onCreate(Msg *msg) { .... } } Now, as Jarret suggested in this thread, I could have an array of = delegates instead of an array of functions. But then, I would have to make this array = non-static, and the initialization would be in the non-static constructor also. IMHO, the flexibility you gain being able to handle a WM with a member = function of another class doesn't worth the additional cost of having the message map = duplicated into each of the window objects. And this flexibility isn't really so useful as it= = could seem, because (IMHO again) it breaks encapsulation. So, if I want a static WM map per subclass, I'll need pointers to member= = functions :-( I have also put the Delegate_Function hack into a template so I can use = it = with functions with different parameters. I hope my intentions are clearer now. If you have any suggestions to = improve this, they'll be welcome. -- Pinzo
Sep 08 2005