Solved

where are Pointers to function used

Posted on 1998-10-22
8
145 Views
Last Modified: 2010-04-02
What is the use of Function Pointers and where are these used ?
Is it considered a good programming practise to use these or
are these to be avoided ?
0
Comment
Question by:jassi
  • 6
8 Comments
 
LVL 8

Accepted Solution

by:
Answers2000 earned 100 total points
ID: 1175740
This will take me several minutes to type, please see the answer in my next comment (I do this so another Expert doesn't waste time typing an identical answer)
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1175741
A function pointer is a variable that holds an address of a function

What this means is that a function (say function-A) can decide which function to call at runtime (example:whether to call function-B or function-C)

There are many reasons why you may need this behaviour. Here are some examples:

1. A library routine supplies an algorithm, but doesn't provide the data.  The code that calls the library routine provides the data - through a function that provides it.

Example:
qsort - in the C Standard library

qsort provides a function to sort a block of memory of memory using the Quick Sort Algorithm.  It assumes the (a) the data is a continuous block of memory, and (b) each item to be sorted is a continuous block -  but makes no other significant assumption.

However the function that calls qsort - may wish to sort ints, strings, or some user-defined record type (example: a user defined struct).  Obviously the compiler/library author can't know before hand how you might use this function.  Therefore the caller is responsible for providing a function to compare the items to be sorted.  The caller provides a function pointer - also known as a call-back function - to the function to compare 2 elements.

Incidentally it is arguable that the qsort C library function could be even further improved by removing the assumptions about the  memory layout (this isn't what the ANSI C standard says, but if you wrote your own version of this function you might decide to do it) - if you provide a 2nd function pointer parameter - to the function to swap 2 elements (this way a caller can provide functions for compare and swap, and use the same underlying algorithm for memory, disk files, or whatever).


You can use the same principle as this entirely within your own programs - to reuse algorithms with multiple data types.


2.  A library routine provides an unknown known amount of data

Example: Windows provides many "enumeration" functions, e.g. EnumWindows

EnumWindows provides a list of windows matching some criteria

The list size may be variable (it may contain 1 item or 1000)

Rather than provide a fixed size array, and rather than make complex assumptions about clean up (e.g. if EnumWindows were to allocate memory for the list who would be responsible for the cleanup - the caller or Windows ?) - INSTEAD you provide a caller back function (a function pointer).  EnumWindows simply calls this function once for each window that matches it's search criteria.  The call-back function can then do whatever it wants over an extended period.


3. Information/Notification over an extended period.

The system, a library routine, or part of your program, needs to tell another piece of code that something has happened (an event or message).  For example windows might need to tell your code whenever the mouse moves over a particular window.  It does this through a function pointer:

- when you create a window - you provide a function pointer to your window's code (in MS Windows this is called a WndProc)
- whenever a message needs to be sent to your code telling it something has happened - Windows calls your code and says - the mouse has moved, the keyboard was used, or whatever
- your routine can then decide how to handle this.


4. Use of functions as data & polymorphism

In C you might have an array of shapes on the screen.  Each shape is represented by a set of bounding coords (say a bouding rectangle) and some function to draw the shape.  If a user-defined struct includes a pointer to a function to draw the shape, you can manipulate the array (example:sort it, delete elements) as data.  Polymorphism basically means common behaviour across all shapes (more on this in my C++ comment below) - example: all shapes include a function pointer to a "DrawTheShape" function - which is different for each kind of shape (square, ellipse, line, etc.)

Some C++ comments below
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1175742
>> Is it considered a good programming practise to use these

It is considered good programming practisre to use these - **when** they need to be used.  Like anything else - it is good only when appropriate.

For some code, (#1 and #3 above)  there is no practical alternative in C.  For some code - it is considered good programming practise if it meets your design goals (which may be clarity, performance etc.)

It is simply a tool use it well.

Function Pointers can be tricky, so it is easy to make mistakes.

C++ offers some alternatives - see my next & last comment
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 8

Expert Comment

by:Answers2000
ID: 1175743
C++ offers 2 alternatives to function pointers

A. Template classes & functions


Templates are not an exact alternative to function pointers, but can solve many of the same problems, without being so tricky (they have _different_ tricks).  Basically the template provides an outline for an algorithm, but can leave out things like data-type, and this is filled in, when code is used.

Example: part of the C++ standard library (STL = standard template library).  Provides a sort routine (called "sort".  The coding call it provides the data.  The template makes some assumptions about the operations available on the data provided (example: items can be compared) - but only minimal assumptions.  In the case of the "sort" routine it can do whatever Q sort can.

This is mainly an alternative way of doing #1 from my original comment,

Templates can also do additional stuff



B. Virtual functions.

This is the C++ way of doing function pointers (you can still use C style function pointers too).

If you pass a pointer to class containing a virtual or pure virtual function, this is equivalent to passing a function pointer, but is type safe (the compiler checks better so you are less likely to make errors).

Example - library might define (it doesn't)
class MyQSortBase
{
public:
   virtual int Compare( int i, int j ) const =  0 ; // pure virtual
   virtual void Swap( int i, int j ) = 0 ; // pure virtual
} ;

void MyQSort( int nItemCount, MyQSortBase * pUserClass ) ;

The caller code then derive a class from MyQSortBase (and actually implement the code to do compare and swap) and pass a pointer to an object to this type to MyQSort to actually do the sort.  This is equivalent to passing 2 function pointers.

Extending this principle, you can solve all the original problems I gave in my comment (using C++) without using function pointers.

In C++ there are still some reasons to use function pointers.
- Different manufacturers C++ compilers are generally not compatible for passing classes/objects.  If you write a library or use somebody else's library, a function pointer instead of a class pointer may be more likely to be compatible with somebody else's code.
- Function pointers may interface easier to other languages (e.g. C or Assembler) - do you want people interfacing to your code to know/care your write C++ including which compiler version
- Function pointers may be part of a legacy standard you don't want to break (e.g. the Windows API)
- Virtual functions may be slightly slower than function pointers.  - in most cases this is probably not a consideration - but may be if called a 1,000,000 times or if in a time critical code section (e.g. port handling)






0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1175744
Oh one final point - the MyQSort function is in the jargon - "Polymorphic".

More commonly in books you'll see this behaviour to manipulate arrays of objects, all of which share some common behaviour

example:
Shapes program referred to in original #4

All shapes - might have a "draw your self" function, and a "show the shapes properties" function - both of which are virtual or pure virtual members of the base class of all shapes
0
 
LVL 22

Expert Comment

by:nietod
ID: 1175745
Impressive answer--your fingers must be tired too.

I would just like to add that whenever possible you should use virtual functions instead of function pointers.  You need function pointers only when dealing with code writen by someone else that uses function pointers (like the C sort procedure or the operating system's functions) or if your code must interface with a non-C++ language (Like if it is in a DLL that can be called by programs written in other languages).  For all other cases, that is when writting code that will be used within C++, you should always use virutal functions.  They are much safer and much more powerful.  There is nothing that can be done with a function pointer that can't be done using virtual functions.  (Virtual functions use function pointers in fact, but they allow the compiler to do a lot of safety checking and do a lot of the work for you.)
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1175746
thanks nietod - i don't think I would have started if I realized what the answer would have grown too!

Good point, but I think i kind of said it (section B in 3:56 comment - para#2) - but no harm in emphasizing the point (or should I said pointer? <g> and <groan> )

0
 

Author Comment

by:jassi
ID: 1175747
Thanx a lot Answers2000.... very clear and impressive answer..... wish there was something higher than excellent in the ratings scheme... thanx once again
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question