Pointers to Functions in C++
Overview
A variable pointer points to the address of a function. Similarly, a function pointer points to the address of the first line of code in a function. Function pointer in C++ is very useful as it can be passed as a parameter to a different function, thus making the functionality of callbacks easy to implement in C++. Apart from this, a function pointer in C++ can also be used as a return type for functions in C++.
What is the Address of a Function?
We know that when we declare variables in our code, they are stored in the memory and hence have a corresponding memory address. This is true for not just variables, but for the complete code in C++. The code we write in C++ is written in a high-level programming language that is not understandable by a computer and needs to be converted into a low-level language by a compiler. To accomplish this, all of these instructions have memory allocated in the RAM. Hence, just like variables in our code, the functions we declare also have a corresponding memory address associated with them. The address, to be precise, stores the address of the first instruction line of the function so that whenever this function is called, this address is extracted and this is where the code starts its execution for this particular function. This also implies that, just like variables, functions also have pointers to them, that store this address which points to the first instruction of the function in C++.
Syntax for Declaration of Function Pointer in C++
The syntax to declare a function pointer in C++:
When declaring function pointer in C++, first we write the return_type of the corresponding function followed by * and the name of the pointer enclosed in brackets, and then the list of the data types of the parameters the function has, to which this pointer will point. This is consistent with how we declare pointers to variables in C++.
For example, if we declare a function pointer in C++ as
The pointer declared here has the name fun_ptr, and the function it can point to has a return type of void and has two parameters: an integer and a double.
Trailing Return Type in the Declaration or Definition of Function Pointer in C++
In C++, we have the option to use the auto keyword instead of specifying the return type in the declaration of a function. In such a case, we have to declare the return type of the function after the parameter declaration, like:
This is called a trailing return type declaration of a function. Now, we wanted to declare a function pointer for this function, what would be the syntax for this declaration?
So, we just need to declare the pointer just like we declare the function. First, we have the keywords typedef and auto followed by a * and the name of the pointer enclosed in brackets, and then the list of the data types of the parameters the function has, to which this pointer will point. This is followed by an arrow symbol -> and the return type of the function, to which the pointer points. The above-declared pointer will point to the above-declared function fun.
Note - The trailing return type declaration is not required for C++ 14, where the compiler will deduce the return type itself.
Initializing a Function Pointer in C++
We saw in the previous sections, that just like variables in C++, functions also have memory addresses associated with them. We also saw how we can declare a function pointer in C++. Let us now look at how we can initialize this created pointer.
To initialize a function pointer in C++, we need to give it the address of a function. But how to access this address? In C++, the address of a function can be accessed by just writing the function name without the brackets, like func_ptr = fun;. Here the pointer is func_ptr which will now point to the function fun. If we add the brackets to the function name, it becomes a function call. But without it, we can access the address of the corresponding function.
We can also add an & symbol (ampersand) before the function name, just like when initializing pointers to variables. Though, this is optional in the case of a function pointer in C++. Let us look at the code to initialize a function pointer in C++.
Invoking a Function Pointer in C++
We can invoke a function pointer in C++ just like we invoke a normal function. The syntax for the same will be:
Here fun_ptr is the name of the function pointer and arg1, and arg2 are the arguments of the function.
Callback Functions
Callback functions are functions that are executed after a particular event takes place. For example, if a user clicks a button then a text area field should be displayed. In this case, we will have a piece of code that calls our callback function whenever the button is clicked, and then our callback function provides the text area to the user.
Callback functions are generally useful for event handling just as we saw in the previous example. Because callback functions have to be executed after a particular event occurs like a button click. They have to be called or invoked from some other function. In such a case, a function pointer in C++ is very useful, as we can pass a function pointer in C++ as an argument to a different function, and then that function can use the pointer to call our function as a callback whenever some event occurs.
Output
In the above code first, we initialize a function pointer that points to the fun_1() function. Now, the fun_2() function is the one that takes the function pointer as an argument, and hence, fun_1() becomes a callback function. So, from fun_2() we call fun_1() like a callback function.
Facts on Function Pointer in C++ That You Should Know
- Function pointer in C++ points to the address of the first line of the code of the corresponding function they point to, unlike variable pointers that point to the address of data.
- To access the address of a function, we can use just the function name without the brackets. For example, ptr = fun; the pointer ptr holds the address of the function fun.
- Function pointers in C++ cannot be used to allocate or deallocate memory as they point to the address of code and are used for the execution of the code only.
- Just like variable pointers, function pointers in C++ can also be used in an array of function pointers.
- Also, just like variable pointers, a function pointer in C++ can also be used as an argument for another function, or also as the return type of a function.
Example of Address of a Function
We can also get the address of a function in C++. To do this we just require the name of the function whose address is to be returned.
Note: We do not require the function to be called.
Let us understand this better using an example.
Output
In the above code, we print the address of the main() function of the program. To obtain the address we merely specified the name of the function, no brackets, and no parameters were used to output the address of the main() function. As a result, the address of the function is the name of the function without any brackets or arguments passed to it.
Similarly, we also show the address of the add() function using an alternate method that is by using the ampersand symbol (&) before calling the function.
Calling a Function Indirectly
We can also call a function indirectly with the help of a function pointer in C++ by using the name of the function pointer. The syntax of calling a function indirectly through the pointer is similar to calling the function normally. In this case, we just need to define and initialize the pointer, and call the pointer with the brackets. For example, if a pointer ptr points to a function fun, then to call fun indirectly using ptr, the syntax will be ptr();. This will execute the function fun.
Let us look at an example to understand this.
Output
We define the function pointer, int (*funcptr)(int, int), and then store the address of the mult() function/method in funcptr in the above program. This means that the address of the mult() function/method is stored in funcptr. We can now use funcptr to invoke the mult() method. The mult() function is called by the phrase funcptr(5, 7), and the result is put in the mul variable which is later on printed.
Function Pointer in C++ as Return Type
A function pointer in C++ can also be used as a return type for a different function. This means that the particular function will be returning a function pointer as the return type.
But, the online C++ compiler doesn’t allow the return type for a function to be a function pointer in C++, so we will define the function pointer as a custom data type. After this, we can use this newly defined type, which is actually for a function pointer, as the return type for functions.
Let us look at an example to understand this better.
Output
In the above code, firstly, we defined the function pointer as a type to be able to return it as a return type. Then, from the function print(), we return the address of the function add(), which computes the sum of the passed variable with 5. In the main function, we initialize a function pointer and invoke it with the integer variable as an argument to get the result.
Passing Function Pointer in C++ as a Parameter
Similar to what we discussed above, we can also pass a function pointer in C++ as a parameter in another function altogether. For this, we just need to declare the pointer as a parameter of the function according to the syntax of the pointer like
Let us look at an example to understand this better.
Output
In the above code fun_2() is called which takes a function pointer as one of its parameters. The main() function calls the fun_2() function which takes fun_1() 's address as a parameter. In this way, when funcptr() is called, it indirectly calls fun_1() inside fun_2().
References To Functions
An alias or an alternate name is a reference to a function. After you define a function, you must initialize all references to it. A reference to a function cannot be reassigned/transferred once it has been declared. References can be used to call functions and send functions as parameters/arguments to other functions. This means that we can use references as arguments in a function.
The syntax for the same will be:
Here, the function func takes a reference as a parameter.
Let us try to understand this better by an example.
Output
In the above code, we first define two functions namely func_0() and func_1(). func_0() takes a function pointer as a parameter and returns by calling the function that it took as a parameter by simply calling the name of the reference. func_0() first prints the statement and then calls the func_1() which also prints its statement and then returns a value of 5 which is stored in the variable x.
Benefits of Function Pointer in C++
- A function pointer in C++ can be passed as a parameter to a function, thus providing the functionality of implementing callback functions.
- A function pointer in C++ allows you to send along instructions for how to perform something.
- By supplying function pointers in C++ as parameters, you may construct flexible functions and libraries that allow the programmer to determine behavior.
Conclusion
- Just like variables, functions also have pointers to them, that stores the address which points to the first instruction of the function in C++.
- In C++, the address of a function can be accessed by just writing the function name without the brackets.
- Callback functions are functions that are executed when a particular event takes place. This can be achieved by using a function pointer in C++.
- A function pointer in C++ cannot be used to allocate or deallocate memory as they point to the address of the code.
- We can also call a function indirectly with the help of a pointer (function pointer) by using the name of the function pointer in C++.
- A function pointer in C++ can also be used as a return type or as an argument to another function.