【函数指针】

函数指针详解

什么是函数指针

函数指针是指向函数地址的指针变量。与普通指针存储变量地址不同,函数指针存储的是函数在内存中的地址。

cpp 复制代码
// 普通指针:存储变量地址
int a = 10;
int* p = &a;

// 函数指针:存储函数地址
void test() { std::cout << "hello" << std::endl; }
void (*p)() = test; // p存储test函数的地址

为什么需要函数指针

函数指针的核心价值是让函数像变量一样被传递,实现运行时动态选择执行的函数。

cpp 复制代码
void A() {}
void B() {}

void run(void (*f)()) {
    f(); // 执行传入的函数
}

run(A); // 执行A
run(B); // 执行B

这是工厂模式、策略模式等多种设计模式的基础。

直观理解

  • 普通变量:存储数据
  • 函数指针:存储行为(操作步骤)

核心区别:

数据指针指向数据,函数指针指向行为

应用场景

函数指针可以像数据一样存储在各种容器中:

  • map:实现注册模式(如插件系统)
  • vector:存储多个函数
  • 数组:实现简单的命令分发

语法

基本形式

cpp 复制代码
int add(int a, int b) { return a + b; }

// 函数指针定义
int (*p)(int, int) = add;
// 调用
int result = p(2, 3);

简化写法(typedef/using)

cpp 复制代码
// 传统写法
typedef int (*FuncType)(int, int);
// C++11+ 现代写法
using FuncType = int(*)(int, int);

FuncType p = add;

无参数/无返回值

cpp 复制代码
void hello() { std::cout << "Hello" << std::endl; }
void (*fptr)() = hello;
fptr();

作为参数

cpp 复制代码
void execute(void (*func)()) {
    func();
}

execute(hello);

作为返回值

推荐写法(使用typedef/using简化):

cpp 复制代码
using FuncType = int(*)(int, int);

FuncType getFunc() {
    return add;
}

// 1. 调用getFunc函数,获取add函数的指针
FuncType p = getFunc();
// 2. 调用add函数
int result = p(1, 2);

形式总结

场景 形式 示例
指针变量 返回类型 (*指针名)(参数列表) int (*p)(int, int) = add;
typedef/using typedef 返回类型 (*类型名)(参数列表) typedef int(*FuncType)(int, int);
作为参数 void f(返回类型 (*param)(参数列表)) void run(int (*func)(int, int))
作为返回值 typedef/using类型名 f() FuncType getFunc() { return add; }

关键规律(*名字) 必须用括号包起来,否则编译器会认为是函数声明。

本质

函数指针的本质是把函数当成"任务"传递

cpp 复制代码
void life(void (*f)()) {
    f(); // 执行传入的任务
}

void eat() { std::cout << "吃饭" << std::endl; }
life(eat); // 传递"吃饭"任务

简单来说:

普通参数传数据,函数指针传动作

实际应用

你可能已经在使用函数指针的概念,只是换了个名字:

  • 虚函数
  • std::function
  • Lambda表达式
  • 回调函数

这些底层都基于函数指针的思想。

复杂声明解析

对于复杂的函数指针声明:

cpp 复制代码
Plugin* (*FactoryFunc)();

解析:FactoryFunc 是一个返回 Plugin* 且无参数的函数指针。

总结

函数指针是C++中强大的特性,它允许我们:

  • 动态选择执行的函数
  • 实现回调机制
  • 构建灵活的设计模式
  • 提高代码的模块化和可扩展性

核心理解:普通指针指向数据,函数指针指向代码

相关推荐
万法若空4 小时前
C++ <memory> 库全方位详解
开发语言·c++
代码中介商4 小时前
C++ 类型转换深度解析:static_cast、dynamic_cast、const_cast、reinterpret_cast
开发语言·c++
青小莫4 小时前
C++之string(OJ练习)
开发语言·c++·stl
6Hzlia5 小时前
【Hot 100 刷题计划】 LeetCode 199. 二叉树的右视图 | C++ DFS 逆序遍历
c++·leetcode·深度优先
-Marks-5 小时前
【C++编程】STL简介 --- (是什么 | 版本发展历程 | 六大组件 | 重要性缺陷以及如何学习)
开发语言·c++·学习·stl·stl版本
CoderCodingNo6 小时前
【信奥业余科普】C++ 的奇妙之旅 | 12:程序的交互与加工——数据的输入与算术运算
开发语言·c++
yx868xy6 小时前
Cuda加速直线拟合
c++·cuda
蜗牛在听雨6 小时前
基于 C++ 的 UG/NX 二次开发环境配置
c++·二次开发·ug
SimpleLearingAI7 小时前
C++虚函数详解
开发语言·c++