Why to use function pointer? [duplicate] - c++
This question already has answers here:
What is the point of function pointers?
(18 answers)
Closed 4 years ago.
I hope its an extremely repetitive question. And my advance excuse to all the viewers who find it annoying.
Although I am bit experienced programmer, but I cannot justify the use of function pointer over direct call. Scenarios where I unable to find the differences are -
1) callbacks - same can be achieved by direct call.
2) Asynchronous or synchronous event handling - anyway event has to be identified, based on which element no. in function pointer array got updated. But the same can be also done via direct call.
3) In some post I had seen people commenting it is to be used when it is not known which function to call. I didn't get any proper justification for this.
I really appreciate if someone can explain me using above scenarios with practical and really simple realistic example.
Some more things function pointers are often used for:
Runtime polymorphism: You can define a structure that encapsulates a function pointer, or a pointer to a function table. This enables you to call the specified function at runtime, even for a type of client object that did not exist when your library was written. You can use this to implement multiple dispatch or something like the visitor design pattern in C. This is also how C++ classes and their virtual member functions were originally implemented under the hood.
Closures: These can be structures containing a function pointer and one or more of its arguments.
State Machines: Instead of a switch with a case for each state label, I’ve often found it convenient to give the handler for each state its own function. The current state is the function you’re in, the state transitions are tail-recursive calls, and the program variables are parameters. The state labels then become function pointers, which you might store in a table or return from a function.
Higher-Order Functions: Two examples from the C standard library are qsort() and btree(), which generalize the type of elements and the comparison function.
Low-Level Support: Shared-library loaders, for example, need this.
1) callbacks - same can be achieved by direct call.
Not true. For a direct call, the caller must know the function name and signature when the code is compiled, and can only ever call that one function. A callback is defined at runtime and can be changed dynamically, while the caller need only know the signature, not the name. Moreover each instance of an object may have a different callback, whereas with a direct call, all instances must call the same function.
2) Asynchronous or synchronous event handling - anyway event has to be
identified, based on which element no. in function pointer array got
updated. But the same can be also done via direct call.
Not sure what you mean, but an event handler is simply a kind of callback. The event may be identified by the caller and different call-back handlers called through pointers. Your point only stands if there is one event handler for all event types and the user is to be responsible for identification.
3) In some post I had seen people commenting it is to be used when it is not known which function to call. I didn't get any proper justification for this.
See (1) and (2) above. Often it is a means to hook platform independent third-party library code into a specific platform without having to deliver source-code or for system events that require user/application-defined handlers.
I would not sweat it however - if all your application requirements can be resolved without using a pointer to a function, then you don't need a pointer to a function. When you need one, you will probably know. You will most likely encounter it when you have to use an API that requires it before you ever implement an interface yourself that does. For example in the standard library the qsort() function requires a pointer to a function in order to define how two objects of arbitrary type are to be ordered - allowing qsort() to support any type of object - it is a way in C of making a function "polymorphic". C++ supports polymorphism directly, so there is often less need for explicit function-pointers in C++ - although internally polymorphism is implemented using function pointers in any case.
There is a concept in programming called DRY -- don't repeat yourself.
Suppose you have 121 buttons in your UI. Each one of them behaves much the same, except when you press the button, a different operation happens.
You can (A) use virtual inheritance to dispatch to the right operation (requiring a class per button), or (B) use a function pointer (or a std::function) stored in the class in order to call the right "on click" handler, or (C) have every single button be a distinct type.
A virtual function is implemented in every compiler I have examined as a complex table that, in the end, is a collection of function pointers.
So your choices are function pointers or generating 121 completely distinct buttons that happen to mostly behave the same.
In any situation where you want to decouple the caller and the called, you must use something akin to a function pointer. There are a ridiculous number of cases, from work queues to thread off tasks, callbacks, etc.
In tiny programs where everything is hard coded, hard coding every call can work. But hard coded stuff like this doesn't scale. When you want to update those 121 buttons each hand-implemented, knowing their points of customization is going to be ridiculously difficult. And they will fall out of sync.
And 121 is a modest number of buttons. What about an app with 10,000? And you want to update every button's behavior to handle touch-based input?
Even more, when you type erase, you can reduce binary size significantly. 121 copies of a class implementing a button is going to take more executable space than 1 class, each of which stores a function pointer or two.
Function pointers are but one type of "type erasure". Type erasure reduces binary size, provides clearer contracts between provider and consumer, and makes it easier to refactor behavior around the type erased data.
Without function pointers, how would you implement a function which calculates the integral of any real-valued function?
typedef double (*Function)(double);
double Integral(Function f, double a, double b);
1) callbacks - same can be achieved by direct call.
Not in all cases, since the caller may not know at compile-time what function must be called. For instance, this is typical in libraries since they cannot know in advance your code.
However, it can also happen in your own code: whenever you want to re-use partially a function, you can either:
Create several versions of that function, each calling a different function. Duplicates code, very bad maintenance. Good performance unless hit by code bloat.
Pass a function pointer (or callable in general in C++). Flexible, less code, performance might suffer in some cases.
Create a set of branches (if/switch chain), if you know in advance the set of possible functions to call. Rigid, but might be faster than a function pointer for small number of branches.
In C++, create a templated version. Same as the first case, but automated; so good maintenance. Code bloat might be an issue.
Factor out the common code so that callers can call whatever they need piece by piece. Sometimes this isn't possible/easy -- specially when parametrizing complex algorithms that you want to keep reusable (e.g. qsort()). In C++, see the STL (Standard Template Library).
2) Asynchronous or synchronous event handling - anyway event has to be identified, based on which element no. in function pointer array got updated. But the same can be also done via direct call.
Some event systems are designed so that you simply configure which function(s) will be triggered when a given event happens. If this is an external library with a C interface, they have no choice but to use function pointers.
Some other systems let you create your own event loop and you fetch the events somehow and do whatever you want with them; so they avoid callbacks.
3) In some post I had seen people commenting it is to be used when it is not known which function to call. I didn't get any proper justification for this.
See the first case.
Thanks all for actively participating in this discussion. Thanks for giving practical examples like -
1) Implement Library function
2) Look qsort
3) Refer Linux Kernel
4) Generic Heap data structure in C
I feel qsort() void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)) s is quite sufficient to clear my 1) & 3) point.
1) callbacks - same can be achieved by direct call.
3) In some post I had seen people commenting it is to be used when it is not known which function to call. I didn't get any proper justification for this.
Mainly by callbacks - it is a provision of calling a function for which the body is not yet defined. And it expected that the definition of the function will be provided later during run-time. So, compilation won't be hindered due to lack of function definition. Practical use if someone consider above qsort() function. In this the user is responsible for providing the function definition for compare() like -
int compare (int* a, int* b)
{
//User defined body based on problem requirement
}
Lets consider a practical scenario where multiple threads have their respective compare function. In case of direct call every thread need to implement their own sorting function or if a common function then implementation would be much more bulky. But by using the callback method all threads can use same function for sorting, since the sorting algo remain same for all threads.
Considering a layered architecture mainly higher layers have an abstract view of lower layer. So, here if say we have qsort() function [User defined qsort] implemented at application layer and lets say underlying application there is a ADC driver layer which capture sample and provide to application for sorting. Then for application it is not necessary to understand the definition of function responsible for collecting and providing the samples. But application will only focus on obtaining the sample. Hence, that main application won't know which function to call. Respective ADC driver will simply make a call to application using the qsort() and provide needful data.
Regarding 2 point still confused -
2) Asynchronous or synchronous event handling - anyway event has to be identified, based on which element no. in function pointer array got updated. But the same can be also done via direct call.
From above discussion I conclude that if event handlers pointed to some library function, then it need to be implemented via pointer to function. And secondly to create an independent and handy code it is necessary to maintain function pointer. Lets say between application and driver we have an interfacing layer. So, if either application or driver changes anytime it won't affect or very least affect each other. And this interface layer is implemented using pointer to function. But consider below scenario -
int (*fptr[10]) (void) =
{
function1; //function for starting LED
function2; //function for relay operation
.
.
function10; //function for motor control
}
lets say we have GPIO0.0 - GPIO0.10 has been mapped to the function pointer array. i.e. GPIO0.0 - 0th element of fptr
.
.
GPIO0.10 - 10th element of fptr
These GPIO pins has been configured for level triggered interrupt and their respective ISR will update the array element no. i=GPIO_Value; further the scheduler have an thread which will call the function pointer array -
fptr[i]();
Does the use of function pointer is justifiable here??
Related
Equality comparing boost::function with functor.members.func_ptr
I'm currently trying to implement an event manager in C++. In principle it keeps a map of event types (uint64_t) to a list of boost::function<void(const IEventDataPtr&)>s. User can register new listeners by calling EventManager::add(boost::function<void(const IEventDataPtr&)> delegate, EventType event). However, a user might want to deregister their listener later. This would involve finding this particular function object and removing it from the respective list. I know that boost::function is generally not comparable. When playing around in the debugger I found that by comparing functor.members.func_ptr I could actually do what I was trying to do. It works as expected for lambdas, boost::bind, static member functions and regular functions. Is this safe to do? Are there any gotchas? My expectation would be for the same object (i.e. the same lambda, function, etc. pp.) to have the same address, that is not shared with others.
How to have a higher level function check variables within lower functions via pass by reference?
We haven't really covered pointers but have been learning about passing by reference (the & pointer will be covered later). In an exercise, we were asked to write a small question game that would pass values in a simple one class main program between its functions to get things done. If we have a hierarchy where main calls 2 functions: function askNum, and function giveStats, with askNum having a host of functions inside (one on the lower level being checkIfRight). I need to call giveStats which would basically tell the user how well they've guessed over a set of questions. I am glossing over the details because I want to focus on the fact that we can't use value returning functions or global variables. So I have to figure out a way to count the number of guesses correct within checkIfRight and send that info back up the hierarchy of functions to giveStats. I am not sure how to call it though. I have most of the code figured out for this game and implemented simple pass by reference on functions in the same hierarchy, I am confused about having a function outside basically call it. So would there be a variable in main called numCorrect and giveStats would call it after askNum modifies it?
Must objects contain pointer members to be able to communicate with other objects?
I just started learning about design patterns, and I'm having trouble with some should-be-simple concepts. The concepts of some of these patterns make sense, but I'm struggling with how I should implement them in C++. Let's saying I'm working on a problem that implements an observer problem. Let's assume there is only a single observer. That leaves two objects that need to communicate: the subject and the observer. Conceptually, what this pattern is attempting to do is very simple to understand. However, I'm getting bogged down by questions like: where do they objects live? Must they both live within some container? How do they actually make requests from one another? Regarding that last question, is it necessary for each object to a have a data member that references the other object? As in, must the subject contain a pointer to the observer, and must the observer contain a pointer to the subject? So stepping away from the observer. If I have any two objects that are dependent to each other (uni-directionally or bi-directionally), is it necessary that each object have a pointer to its respective object? Thank you,
A typical high-level run-time polymorphic implementation of the observer pattern has the observable object add a data member such as std::vector<Observer*> observers_;, and when something of interest happens the observable's member function iterates over that observers_ calling some function through the Observer*s. There's not necessarily any need for the Observers to keep pointers/references to the observable object, but if it's useful they may do so, or the callbacks from the observable object might pass the this pointer or a reference to *this as a parameter. Simpler observables might only support one Observer* instead of a container thereof. For lower-level / performance-critical code - when it's practical to do so because you know the types involved at compile time - you may prefer to stipulate one or more observers at compile time - perhaps as template arguments. That can allow the dispatch to be inlined and optimised, dead-code elimination to avoid calls to observers that do nothing etc.. where do they objects live? Anywhere that makes sense for the object's general function in the program. For example, if a Database_Server_Connection was observable, it might let other parts of the program register interest in knowing when the connection's established asynchronously, when the connection's dropped, when async requests complete, when the database connection is closed by program code, when the database observable object's destructor runs. The observers could be anywhere else in the program - they might be local objects in some function's scope, possibly in another thread, or they might be in or managed by smart pointers in a static or dynamically allocated container. Must they both live within some container? Nope - as above. How do they actually make requests from one another? Firstly, the code adding observers needs access to the observable object, and normally calls something like observable.add_observer(this); to register themselves, taking care to call observable.remove_observer(this); in their destructor so the observable never accidentally attempts a call into an already "destructed" object. The callbacks then happen using the pointers stashed by add_observer. As above, the callbacks may be passed pointers or references to the observable as arguments, the observers might have stashed away a pointer or reference earlier, or they might not even need one if all the information they need is passed to the callback and they don't need to mutate (call a non-const function on) the observable. So stepping away from the observer. If I have any two objects that are dependent to each other (uni-directionally or bi-directionally), is it necessary that each object have a pointer to its respective object? It's often easiest, but sometimes some other communications mechanism may be used such as a queue or socket, in which case the communicating parties need some manner of pointer/reference/handle/id for that communications mechanism rather than pointers to each other.
Another method you can use to make objects communicate is through an intermediate Queue object, or a socket, or other type of shared memory, so storing a pointer to the other object is not always necessary. In fact, to improve decoupling and write general code it is often better to use an event Queue or a Signal (see design of QT Libraries). Don't take that as meaning that storing a pointer is wrong: it is often a good solution and avoid over-engineering which is expensive (in terms of money, time, and other computing resources).
Effective use of stack vs. heap memory allocation in C++
I am developing a large, complex model (mostly simple math, primarily algebra, but lots of calculations). I did my initial bid assuming I'd have to do everything once, but now the scope has expanded such that I need to run the entire model multiple times (on the same set of underlying assumptions but with a different dataset). Based on my initial needs, I created a bunch of classes, then created dynamic instances of those classes in my main function, passing them by reference to each function as I went. That way, at the end of the main function, I can do all the necessary reporting / output once all of the functions have run. My question is about how to now modify my main function to allow for multiple iterations. A few sample bits of code below, followed by my question(s): // Sample class declaration (in main) vector<PropLevelFinancials> PLF; // Sample function call (functions in other header files) ProcessPropFinancials(vector<PropLevelFinancials>& PLF); // Reporting at the end of main (functions in other header files) OutputSummaryReport(vector<PropLevelFinancials>& PLF, other objects); // What I need to do next // Clear/Delete PLF and other objects, iterate through model again I am quite happy with the speed and result of my current program, so don't need a whole lot of input on that front (although always welcome suggestions). How should I implement the ability to cycle through multiple datasets (I obviously know how to do the loop, my question is about memory management)? Speed is critical. I want to essentially delete the existing instance of the class object I have created (PLF), and then run everything again on a new instance of the object(s). Is this the type of situation where I should use "new" and "delete" to manage the iterations? Would that change my function calls as outlined above? If I wanted to avoid using new and delete (stay on the stack), what are my options?
No. Do not, ever, use new and delete without a highly exceptional cause. std::vector<T> offers a clear() member you can use. I suggest you implement a similar one for your own classes if that is what you need. Or you can simply do PLF = std::vector<T>();, which would work a bit better for your own UDTs without modification, assuming that you wrote them according to the most basic C++ guidelines.
Object Oriented Design - The easiest case, but I'm confused anyway!
When I wrap up some procedural code in a class (in my case c++, but that is probably not of interest here) I'm often confused about the best way to do it. With procedural code I mean something that you could easily put in an procedure and where you use the surrounding object mainly for clarity and ease of use (error handling, logging, transaction handling...). For example, I want to write some code, that reads stuff from the database, does some calculations on it and makes some changes to the database. For being able to do this, it needs data from the caller. How does this data get into the object the best way. Let's assume that it needs 7 Values and a list of integers. My ideas are: List of Parameters of the constructor Set Functions List of Parameters of the central function Advantage of the first solution is that the caller has to deliver exactly what the class needs to do the job and ensures also that the data is available right after the class has been created. The object could then be stored somewhere and the central function could be triggered by the caller whenever he wants to without any further interaction with the object. Its almost the same in the second example, but now the central function has to check if all necessary data has been delivered by the caller. And the question is if you have a single set function for every peace of data or if you have only one. The Last solution has only the advantage, that the data has not to be stored before execution. But then it looks like a normal function call and the class approaches benefits disappear. How do you do something like that? Are my considerations correct? I'm I missing some advantages/disadvantages? This stuff is so simple but I couldn't find any resources on it. Edit: I'm not talking about the database connection. I mean all the data need for the procedure to complete. For example all informations of a bookkeeping transaction. Lets do a poll, what do you like more: class WriteAdress { WriteAdress(string name, string street, string city); void Execute(); } or class WriteAdress { void Execute(string name, string street, string city); } or class WriteAdress { void SetName(string Name); void SetStreet(string Street); void SetCity(string City); void Execute(); } or class WriteAdress { void SetData(string name, string street, string city); void Execute(); }
Values should be data members if they need to be used by more than one member function. So a database handle is a prime example: you open the connection to the database and get the handle, then you pass it in to several functions to operate on the database, and finally close it. Depending on your circumstances you may open it directly in the constructor and close it in the destructor, or just accept it as a value in the constructor and store it for later use by the member functions. On the other hand, values that are only used by one member function and may vary every call should remain function parameters rather than constructor parameters. If they are always the same for every invocation of the function then make them constructor parameters, or just initialize them in the constructor. Do not do two-stage construction. Requiring that you call a bunch of setXYZ functions on a class after the constructor before you can call a member function is a bad plan. Either make the necessary values initialized in the constructor (whether directly, or from constructor parameters), or take them as function parameters. Whether or not you provide setters which can change the values after construction is a different decision, but an object should always be usable immediately after construction.
Interface design is very important but in your case what you need is to learn that worst is better. First choose the simplest solution you have, write it now. Then you'll see what are the flaws, so fix them. Repeat until it's not important to fix them. The idea is that you'll have to get experience to understand how to get directly to the "best" or better said "less worst" solution of some type of problem (that's what we call "design pattern"). To get that experience you'll have to hit problems fast, solve them and try to deeply understand why something was wrong. That's you'll have to do each time you try something "new". Errors are not a problem if you fix them and learn from them.
You should use the constructor parameters for all values, which are necessary in any case (consider that many programming languages also support constructor overloading). This leads to the second: Setter should be used to introduce optional parameters, or to update values. You can also join these methods: expect necessary parameters in the constructor and then call their setter-function. This way you have to do check validity checks only once (in the setters). Central functions should use temporary parameters only (timestamps, ..)
First off, it sounds like you are trying to do too much at once. Reading, calculating and updating are all separate operations, that themselves can probably split down further. A technique I use when I'm thinking about the design of a method or class is to think: 'what do I want the highest-level method to ideally look like?' i.e. think about the separate components of the method and split them down. That's top-down design. In your case, I envisaged this in my head (C#): public static void Dostuff(...) { Data d = ReadDatabase(...); d.DoCalculations(...); UpdateDatabase(d); } Then do the same thing for each of those methods. When you come to passing in parameters to your method, you need to consider whether the data you're passing in is stored or not - i.e. if your class is static (it cannot be instantiated, and is instead just a collection of methods etc) or if you make objects of the class. In other words: each object of the class has a state. If the parameters can indeed be considered to be attributes of the class, they define its state, and should be stored as private variables with getters and setters for each, where neccessary. If the class instead has no state, it should be static and the parameters passed directly to the method. Either way, it is common, and not considered bad practice, to have both a constructor and a few get / set functions where neccessary. It is also common to have to check the state of the object at the beginning of a method, so I wouldnt worry about that. As you can see, it largely depends on what else you are doing in this class.
The reason you can't find many resources on this is that the 'right' answer is hugely domain-specific; it depends heavily on the specific project. The best way to find out is usually by experiment. (For example: You're right about the advantages of the first two methods. An obvious disadvantage is the use of memory to store the data the whole time the object exists. This disadvantage doesn't matter in the least if your project needs two of these data objects; it's potentially a huge problem if you need a very large number. If it's a big live dataset, you're probably better querying for data as you need it, as implied by your third solution... but not definitely, as there are times when it's better to cache the data.) When in doubt, do a quick test implementation with a simplest-possible interface; just writing it will frequently make it clearer what the pros and cons are for your project.
Specifically addressing your example it seems as though you are still thinking too procedurally. You should make an object that initialises the connection to the database doing all relevant error checking. Then have a method on the object that writes the values in whatever convenient way you prefer. When the object is destroyed it should release the handle to the database. That would be the object oriented way to approach the problem.
I assume the only responsibility of your WriteAddress class is to write an address to a database or an output stream. If so, then you should not worry about getters and setters for the address details; instead, define an interface AddressDataProvider that is to be implemented by all classes with which your WriteAddress class will collaborate. One of the methods on that interface would be GetAddressParts(), which would return an array of strings as required by WriteAddress. Any class that implements that method will need to respect this array structure. Then, in WriteAddress, define a setter SetDataProvider(AddressDataProvider). This method will be called by the code that instantiates your WriteAddress object(s). Finally, in your Execute() method, obtain the data that are required by calling GetAddressParts() on the "data provider" that you set and write out your address. Notice that this design shields WriteAddress from subsidiary activities that are not strictly part of its responsibilities. So, WriteAddress does not care how the address details are retrieved; it does not even care about knowing and holding the address details. It just knows from where to get them and how to write them out. This is obvious even in the description of this design: only two names WriteAddress and AddressDataProvider come up; there is no mention of database or how to pass the address details. This is usually an indication of high cohesion and low coupling. I hope this helps.
You can implement each approach, they don't exclude each other, then you're going to see which are most useful.