www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - delegate reference

reply "Saaa" <empty needmail.com> writes:
abstract class C
{
 int method();
}
class C2:C
{
 int method() return 2;
}
class C3:C
{
 int method() return 3;
}
int delegate() deleg;
void main()
{
 C c;
 C2 c2 = new C2;
 C3 c3 = new C3;
 c=c2;
 deleg = &c.method;
 writefln(deleg()); // 2
 c=c3;
 writefln(deleg()); // 2
 // I expected this to write 3, why is this not so?
Sep 09 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
  deleg = &c.method;
  writefln(deleg()); // 2
  c=c3;
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
Sep 09 2009
parent reply "Saaa" <empty needmail.com> writes:
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
news:h88cck$1orc$1 digitalmars.com...
 Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
  deleg = &c.method;
  writefln(deleg()); // 2
  c=c3;
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
but isn't deleg pointing to c's method?
Sep 09 2009
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
 "Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
 news:h88cck$1orc$1 digitalmars.com...
 Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
  deleg = &c.method;
  writefln(deleg()); // 2
  c=c3;
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
but isn't deleg pointing to c's method?
Yes... just because you change what c points to doesn't magically rewrite all other references. You might want to read http://digitalmars.com/d/1.0/type.html#delegates
Sep 09 2009
parent reply "Saaa" <empty needmail.com> writes:
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
news:h88i4n$235l$1 digitalmars.com...
 Saaa wrote:
 "Daniel Keep" <daniel.keep.lists gmail.com> wrote in message
 news:h88cck$1orc$1 digitalmars.com...
 Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
  deleg = &c.method;
  writefln(deleg()); // 2
  c=c3;
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
but isn't deleg pointing to c's method?
Yes... just because you change what c points to doesn't magically rewrite all other references.
deleg points to c and c points to c2 and later to c3 while deleg still point to c. Thus when calling deleg it points to c which now points to c3, thus writing '3'. maybe I don't understand what "C c;" and "c=c3;" does? Isn't c a pointer to a C object?
 You might want to read http://digitalmars.com/d/1.0/type.html#delegates
I've read that one a few times now :D
Sep 09 2009
parent BCS <none anon.com> writes:
Hello Saaa,

 "Daniel Keep" <daniel.keep.lists gmail.com> wrote in message
 news:h88i4n$235l$1 digitalmars.com...
 
 Saaa wrote:
 
 "Daniel Keep" <daniel.keep.lists gmail.com> wrote in message
 news:h88cck$1orc$1 digitalmars.com...
 
 Saaa wrote:
 
 abstract class C
 {
 int method();
 }
 class C2:C
 {
 int method() return 2;
 }
 class C3:C
 {
 int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
 C c;
 C2 c2 = new C2;
 C3 c3 = new C3;
 c=c2;
 deleg = &c.method;
 writefln(deleg()); // 2
 c=c3;
 writefln(deleg()); // 2
 // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
but isn't deleg pointing to c's method?
Yes... just because you change what c points to doesn't magically rewrite all other references.
deleg points to c and c points to c2 and later to c3 while deleg still point to c. Thus when calling deleg it points to c which now points to c3, thus writing '3'.
deleg dosn't have pointer to c, it has a pointer to an object, that is a /copy/ of the reference c.
Sep 09 2009
prev sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Saaa wrote:
 "Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
 news:h88cck$1orc$1 digitalmars.com...
 Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
c --> c2.method ^ | deleg ---
  deleg = &c.method;
  writefln(deleg()); // 2
  c=c3;
Now: c --> c3.method c2.method ^ | deleg ---
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
but isn't deleg pointing to c's method?
Yes, to previous c's method. See above. Remember that a delegate is a pair: an instance and it's method. You can't just point to a class' method, you are always pointing to a instance's method. (that's why my arrows point to the dot :-P)
Sep 09 2009
parent reply "Saaa" <empty needmail.com> writes:
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message 
news:h88i6o$23hh$1 digitalmars.com...
 Saaa wrote:
 "Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
 news:h88cck$1orc$1 digitalmars.com...
 Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
c --> c2.method ^ | deleg ---
  deleg = &c.method;
  writefln(deleg()); // 2
  c=c3;
Now: c --> c3.method c2.method ^ | deleg ---
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
Because you didn't reassign deleg.
but isn't deleg pointing to c's method?
Yes, to previous c's method. See above. Remember that a delegate is a pair: an instance and it's method. You can't just point to a class' method, you are always pointing to a instance's method. (that's why my arrows point to the dot :-P)
Ok, disregard my last comment :D How should I do this then?
Sep 09 2009
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
 Ok, disregard my last comment :D
 How should I do this then? 
class Foo { C* c; this(ref C c) { this.c = &c; } int invoke() { return (*c).method(); } } void main() { // ... deleg = &(new Foo(c)).invoke; } Or something similar. This is dangerous. Do not allow either the Foo instance or the delegate to survive past the end of c's scope. It is simpler and safer to just update the delegate.
Sep 09 2009
parent "Saaa" <empty needmail.com> writes:
 class Foo
 {
  C* c;

  this(ref C c)
  {
    this.c = &c;
  }

  int invoke()
  {
    return (*c).method();
  }
 }

 void main()
 {
  // ...
  deleg = &(new Foo(c)).invoke;
 }

 Or something similar.

 This is dangerous.  Do not allow either the Foo instance or the delegate
 to survive past the end of c's scope.

 It is simpler and safer to just update the delegate.
Thanks!
Sep 09 2009
prev sibling parent reply BCS <none anon.com> writes:
Hello Saaa,

 How should I do this then?
C c; C2 c2 = new C2; C3 c3 = new C3; c=c2; auto dg = { return c.method(); }; c=c3;
Sep 09 2009
parent reply "Saaa" <empty needmail.com> writes:
 Hello Saaa,

 How should I do this then?
C c; C2 c2 = new C2; C3 c3 = new C3; c=c2; auto dg = { return c.method(); }; c=c3;
I actually did it like this before :) Thanks But like this I need to do the "c is null" checking within the function literal. I'm not sure how these function literals are implemented; will the size of the function have any impact on speed? Or does the compiler handle them like any other function and just thinks of a name itself ?
Sep 09 2009
parent reply BCS <none anon.com> writes:
Hello Saaa,

 Hello Saaa,
 
 How should I do this then?
 
C c; C2 c2 = new C2; C3 c3 = new C3; c=c2; auto dg = { return c.method(); }; c=c3;
I actually did it like this before :) Thanks But like this I need to do the "c is null" checking within the function literal. I'm not sure how these function literals are implemented; will the size of the function have any impact on speed?
No more than with normal functions.
 Or does the compiler handle them like any
 other
 function and just thinks of a name itself ?
Exactly. If you compile with DMD and the -v flag you can see what names it gives them.
Sep 09 2009
parent "Saaa" <empty needmail.com> writes:
 Or does the compiler handle them like any
 other
 function and just thinks of a name itself ?
Exactly. If you compile with DMD and the -v flag you can see what names it gives them.
:) nice Thanks!
Sep 09 2009