• Advertisement
Sign in to follow this  

Function pointer/delegates

This topic is 2995 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've never used them beyond trivial tutorial examples. Maybe I'm stubborn, but I've never seen the point. Could someone make the argument for using them. Maybe give a concrete example where they would be a better solution than the alternatives.

Share this post


Link to post
Share on other sites
Advertisement
A reasonable place to start would probably be here and here. Each of these function would be much less useful if they didn't make use of callbacks/functors.

It looks like there's a couple of examples in the Wikipedia article as well.

Share this post


Link to post
Share on other sites
Well what would be the alternatives? Say you want to set up an observer pattern so an object can receive an event when a property changes, without function pointers or delegates how would you achieve this?

Scott

Share this post


Link to post
Share on other sites
Well obviously if a library function asks for a function pointer...

I was talking more in a general sense. I would pass objects of a derived from some abstract class type that implement a method.

For example Console.WriteLine(object) Calls the .ToString method on the object, which your objects can overload.

Share this post


Link to post
Share on other sites
The GUI library gtkmm uses signals to communicate between objects. A signal is basically a container of function pointers. If I put a button in my window, it will issue a signal when it's clicked. This means that it will call all the function pointers in the container. That way I can create a button and attach to it whatever I want to happen when it's clicked.

The only alternative I can think of is having a class Button that has a virtual function on_click() and every time you want to put a button in your window you need to derive from class Button and define your own on_click(). I think this would be much more cumbersome.

Another place where I've used function pointers is in writing networking code, where the program is basically a loop around select(), and when certain events happen (a new TCP client connection has arrived, there is something to read from a socket, a socket is ready to receive more data, etc.) you need to do something about them. I made an object that implements the loop around select(), and you could register a file descriptor for it to monitor, together with what functions to call when select() determines that you can read or write or that there was an error. This allowed me to write the program without a long and complicated main loop that does everything and that quickly turns into a maintenance nightmare.

Share this post


Link to post
Share on other sites
Quote:
Original post by alvaro

The only alternative I can think of is having a class Button that has a virtual function on_click() and every time you want to put a button in your window you need to derive from class Button and define your own on_click(). I think this would be much more cumbersome.


That is usually what I do. In all cases where I've thought function pointers MAY have been helpful, I had already had such an inheritances in existence already. I found it much simpler to just implement the virtual function.

And in your GUI example, couldn't that have just been done using the Command pattern?

Share this post


Link to post
Share on other sites
Quote:
Original post by Grain
That is usually what I do. In all cases where I've thought function pointers MAY have been helpful, I had already had such an inheritances in existence already. I found it much simpler to just implement the virtual function.

I guess it's a matter of preference. Doing it with signals allows you to keep things more separate. The button class doesn't know anything about what happens after the event is sent out, and the class that does the work doesn't know if the event came from the button or from somewhere else. The only part of the code that knows about this is the one that sets things up, which is that one that connects the two objects.

Quote:
And in your GUI example, couldn't that have just been done using the Command pattern?

Perhaps. I just think callbacks are a more natural way to go about it.

Share this post


Link to post
Share on other sites
Quote:
Original post by alvaro
every time you want to put a button in your window you need to derive from class Button and define your own on_click().


And that sucks. Why add 2 more files and write a whole new class when you could've done a simple assignment?

Share this post


Link to post
Share on other sites
Inheritance is the single tightest coupling that can possibly exist in a software system. What happens if you ship some library, and later on you're like "oh I sure wish it could respond to Bar() messages in addition to Foo() messages". Now you have to change the base interface, or worst case scenario you have to make a class implement a new interface. Every single client of this class now has to be recompiled. This makes it an extensibility nightmare.

With delegates there is no coupling at all. You can make a generic function pointer that refers to a member function of some object, a global function, or even a functor (function object). You can pass this around to anything that has no idea where it's coming from.

Modern C++ design techniques even allow you to use partial function evaluation.


Real world application:

You're doing asynchronous i/o on a disk. When you want to initiate an asynchronous read you allocate a buffer of the appropriate size, send it off to the async i/o library, and pass it a callback to invoke when reading is complete. But the callback it expects only has parameters for the number of bytes successfully read and an error code. You could store the buffer in your class somewhere, but in the handler how would you later associate that buffer with the specific operation? After all, it's asynchronous so you could initiate 10 operations at once and they can complete out of order.

So you write your callback handler to take the buffer as an argument, then an integer, and then an error code. But how do you pass this function to something expecting something with a different signature? Using partial application, you can dynamically create a new function which has the first parameter "hardcoded" to anything you want. In this case, you hardcode the buffer and leave the other two parameters unspecified. The result is a new function that looks exactly like what the async i/o library wants. When it invokes it using only 2 arguments, it ends up in your function with 3 arguments, where the first parameter is the value hardcoded from the point of invocation of the original async operation.

You'd be dead in the water with an interface approach.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
Quote:
Original post by alvaro
every time you want to put a button in your window you need to derive from class Button and define your own on_click().


And that sucks. Why add 2 more files and write a whole new class when you could've done a simple assignment?


You make it sound as if I were advocating that solution... :)

Quote:
Original post by alvaro
every time you want to put a button in your window you need to derive from class Button and define your own on_click(). I think this would be much more cumbersome.


Share this post


Link to post
Share on other sites
Ah yes, in retrospect it does seem that way. Just re-affirming the suckiness of forcing an inheritance hierarchy to do stuff. Sorry if that wasn't clear.

Share this post


Link to post
Share on other sites
Quote:
Original post by Grain
Maybe I'm stubborn, but I've never seen the point.


std::transform(str.begin(), str.end(), str.begin(), toupper);

In this context, toupper is a function pointer.

Share this post


Link to post
Share on other sites
Quote:

You'd be dead in the water with an interface approach.




class ButtonEvents_btn1: public ButtonEvents{
A* a;
public:
ButtonEvents( A* a1 ): a(a1){}
void onClick(){
//stuffs
}
void onMOver(){}
};

Button Button1;
Button1->setEventHandler( new ButtonEvents_btn1(this ) );

OutToDll( &Button1 );




Share this post


Link to post
Share on other sites
Quote:
Original post by cache_hit
What happens if you ship some library, and later on you're like "oh I sure wish it could respond to Bar() messages in addition to Foo() messages". Now you have to change the base interface, or worst case scenario you have to make a class implement a new interface. Every single client of this class now has to be recompiled.

There's no need to alter the base interface and to recompile the classes implementing it. I see two alternatives: Create a new interface containing the Bar() signature, which can be implemented by the classes that also want to respond to Bar()-messages, or derive an interface from the base that adds the signature. Classes that are only aware of Foo()-messages and implement the base interface remain untouched.

Quote:
Original post by cache_hit
You'd be dead in the water with an interface approach.

Not sure why you'd be "dead in the water". You can solve such a scenario using the proxy pattern, or one of its relatives.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement