3 ms·
Yeah, if you can't grasp 'this', good luck figuring out delegates. (Note: Some/many languages call these "Closures") 'this' is just a context pointer. classes
by katastic 9y ago
Yeah, if you can't grasp 'this', good luck figuring out delegates. (Note: Some/many languages call these "Closures") 'this' is just a context pointer.
classes don't actually store their functions (except virtual ones).
class A{
int data;
void method1(int input){data = input;}
}
A my_instance;
is actually
struct A {int data;}
method1_for_struct_A(A *context, int input){ context->data = input; } //normal local function
A my_instance;
and this:
my_instance.method1(3);
becomes this:
method1_for_struct_A(my_instance, 3);
//send a pointer to the class we're operating on
And once you understand that, delegates are easy, because they're just... sending the context pointer around. So in D:
//note: global function, NOT apart of any class.
delegate void my_function(int input)
{
data = input; //where is data coming from?
// the surrounding context.
}
void my_test_function()
{
int data = 2;
my_function(3); // is a delegate and gets implicitly sent the context
//pointer for my_test_function, and now, it can access data.
// Note this is a RUN-TIME adjustable function. Delegates can be passed
// around.
}
and internally my_function is actually (note the pattern):
void my_function(context_pointer, int input)
{
context_pointer.data = input;
}
and the compiler implicitly sends the context with it:
my_function(3) becomes
my_function(my_test_function_context, 3);
So basically, delegates are just an extension of what classes already use under-the-hood. Delegates are "fat" function pointers. Function pointers point to a function, and the "fat" pointer includes an additional "context" pointer to the surrounding data frame so you can dereference it to access the surrounding data. You can do all of this in plain C if you don't mind writing all the boilerplate code yourself.
Virtual functions are similar to delegates. The class actually contains the function pointer / delegate instead of re-writing it at compile-time. Which allows them to be overridden at run-time. Whereas "this" usually means you can figure it out statically, at compile-time, so the function call is a pure function call and doesn't incur the penalty of looking up a pointer for the virtual call.
I bet I'm probably missing something or slightly off here or there, so someone feel free to chime in and correct me. Consider the code pseudo-code. I might have flipped something from memory.