C++ 函数指针(Function Pointer)详解
函数指针 是指向函数的指针,它可以存储函数地址 ,并通过该指针调用函数 。函数指针在回调函数、策略模式、动态函数调用等场景中非常有用。
1. 什么是函数指针?
函数指针是一个指向函数的指针 ,它存储的是函数的地址 ,并允许通过指针调用该函数。
📌 语法
            
            
              cpp
              
              
            
          
          返回类型 (*函数指针名)(参数列表);
        2. 基本示例
(1)定义和使用函数指针
            
            
              cpp
              
              
            
          
          #include <iostream>
// 普通函数
void hello() {
    std::cout << "Hello, Function Pointer!" << std::endl;
}
int main() {
    void (*funcPtr)();  // ✅ 定义函数指针
    funcPtr = hello;    // ✅ 让指针指向 `hello` 函数
    funcPtr();          // ✅ 通过指针调用函数
    return 0;
}
        📌 输出
Hello, Function Pointer!
        ✅ funcPtr 存储 hello 函数地址,并通过 funcPtr() 调用它。
3. 带参数和返回值的函数指针
            
            
              cpp
              
              
            
          
          #include <iostream>
// 带参数和返回值的函数
int add(int a, int b) {
    return a + b;
}
int main() {
    int (*funcPtr)(int, int);  // ✅ 定义函数指针
    funcPtr = add;             // ✅ 让指针指向 `add`
    std::cout << funcPtr(3, 5) << std::endl;  // ✅ 通过指针调用 `add(3, 5)`
    return 0;
}
        📌 输出
8
        ✅ funcPtr 存储 add() 地址,调用 funcPtr(3, 5) 计算 3 + 5。
4. 函数指针作为函数参数
函数指针可以作为回调函数,在函数内部调用:
            
            
              cpp
              
              
            
          
          #include <iostream>
// 定义回调函数类型
void process(int a, int b, int (*op)(int, int)) {
    std::cout << "Result: " << op(a, b) << std::endl;
}
// 具体实现
int add(int x, int y) { return x + y; }
int multiply(int x, int y) { return x * y; }
int main() {
    process(3, 5, add);       // ✅ 传递 `add` 函数
    process(3, 5, multiply);  // ✅ 传递 `multiply` 函数
    return 0;
}
        📌 输出
Result: 8
Result: 15
        ✅ process(3, 5, add) 让 op 绑定到 add(),支持动态调用!
5. 使用 typedef 或 using 简化函数指针
函数指针的语法比较复杂,可以使用 typedef 或 using 来简化。
(1)使用 typedef
        
            
            
              cpp
              
              
            
          
          typedef int (*FuncPtr)(int, int);  // ✅ 定义函数指针类型
int subtract(int a, int b) { return a - b; }
int main() {
    FuncPtr ptr = subtract;  // ✅ 使用 `FuncPtr`
    std::cout << ptr(10, 3) << std::endl;
}
        (2)使用 using(C++11)
        
            
            
              cpp
              
              
            
          
          using FuncPtr = int (*)(int, int);  // ✅ 定义函数指针类型(C++11)
int subtract(int a, int b) { return a - b; }
int main() {
    FuncPtr ptr = subtract;  // ✅ 使用 `FuncPtr`
    std::cout << ptr(10, 3) << std::endl;
}
        ✅ typedef 和 using 让代码更简洁!
6. 函数指针数组
函数指针可以组成数组,实现动态选择函数:
            
            
              cpp
              
              
            
          
          #include <iostream>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int main() {
    int (*operations[3])(int, int) = { add, subtract, multiply };  // ✅ 函数指针数组
    std::cout << operations[0](3, 4) << std::endl;  // 3 + 4 = 7
    std::cout << operations[1](7, 2) << std::endl;  // 7 - 2 = 5
    std::cout << operations[2](3, 3) << std::endl;  // 3 * 3 = 9
}
        📌 输出
7
5
9
        ✅ 使用索引动态调用不同函数,提高灵活性!
7. C++11 std::function(更现代的方式)
C++11 提供了 std::function 作为函数指针的现代替代 ,它支持Lambda 表达式、成员函数、绑定参数等:
            
            
              cpp
              
              
            
          
          #include <iostream>
#include <functional>  // ✅ 引入 `std::function`
int add(int a, int b) { return a + b; }
int main() {
    std::function<int(int, int)> func = add;  // ✅ 绑定普通函数
    std::cout << func(3, 5) << std::endl;     // ✅ 运行
}
        ✅ std::function 允许存储更复杂的调用目标,如 Lambda 和成员函数!
8. 结论
| 功能 | 函数指针 | **std::function(C++11+) | 
|---|---|---|
| 存储普通函数 | ✅ 支持 | ✅ 支持 | 
| 存储 Lambda | ❌ 不支持 | ✅ 支持 | 
| 存储成员函数 | ❌ 复杂 | ✅ 方便 | 
| 类型安全 | ❌ 可能出错 | ✅ 更安全 | 
| 适用场景 | 轻量级回调 | 泛型函数封装 | 
🚀 推荐:C++11 及以上,使用 std::function 代替传统函数指针! 🚀
是的,typedef 在 C++ 中的作用是 给已有类型取别名,但在函数指针的场景中,它可以让复杂的函数指针声明变得更易读和使用。
1. 为什么 typedef 可以用于函数指针?
函数指针的标准声明可能会很复杂,例如:
            
            
              cpp
              
              
            
          
          int (*funcPtr)(int, int);
        这意味着 funcPtr 是一个指针,指向一个接受两个 int 参数并返回 int 的函数。
如果我们要在多个地方使用这个函数指针类型,每次都要写 int (*)(int, int),这既冗长又容易出错。使用 typedef 让它更清晰:
            
            
              cpp
              
              
            
          
          typedef int (*FuncPtr)(int, int);
        这表示:
- 
FuncPtr是一个新的类型别名 ,它等价于int (*)(int, int)。 - 
现在,我们可以直接使用
FuncPtr来定义函数指针:cppFuncPtr ptr; // 等价于 int (*ptr)(int, int); 
2. typedef 在函数指针中的使用
✅ 使用 typedef 简化函数指针
        
            
            
              cpp
              
              
            
          
          #include <iostream>
typedef int (*FuncPtr)(int, int);  // ✅ 定义函数指针类型别名
int add(int a, int b) { return a + b; }
int main() {
    FuncPtr ptr = add;  // ✅ `ptr` 现在是一个函数指针
    std::cout << ptr(3, 5) << std::endl;  // ✅ 调用 `add(3, 5)`
}
        📌 输出
8
        ✅ FuncPtr 让 ptr 变得易读,等价于 int (*ptr)(int, int);。
3. typedef 用于函数指针数组
函数指针数组允许存储多个函数,并动态选择不同的函数执行:
            
            
              cpp
              
              
            
          
          typedef int (*FuncPtr)(int, int);  // ✅ 定义函数指针别名
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
    FuncPtr operations[] = { add, subtract };  // ✅ 函数指针数组
    std::cout << operations[0](5, 3) << std::endl;  // ✅ add(5, 3)
    std::cout << operations[1](5, 3) << std::endl;  // ✅ subtract(5, 3)
}
        📌 输出
8
2
        ✅ operations[0] 选择 add(),operations[1] 选择 subtract()。
4. C++11 using 替代 typedef
C++11 提供了 using 作为 typedef 的更现代的替代:
            
            
              cpp
              
              
            
          
          using FuncPtr = int (*)(int, int);  // ✅ C++11 写法
        与 typedef 等价,但语法更直观:
            
            
              cpp
              
              
            
          
          FuncPtr ptr = add;
        🚀 推荐使用 using,可读性更强!
5. 结论
| 功能 | typedef 方式 | 
using 方式(C++11) | 
|---|---|---|
| 定义函数指针别名 | typedef int (*FuncPtr)(int, int); | 
using FuncPtr = int (*)(int, int); | 
| 定义函数指针数组 | FuncPtr arr[2]; | 
FuncPtr arr[2]; | 
| 可读性 | ⭐⭐⭐ | ⭐⭐⭐⭐(更直观) | 
| 推荐度 | ✅ 传统 C++ 适用 | ✅ 现代 C++ 推荐 | 
✅ typedef 可以给复杂类型(如函数指针)取别名,提升可读性 ,但在 C++11 及以上,推荐使用 using 替代 typedef! 🚀