当前位置: 首页 > web >正文

【C++】C++函数指针详解与实用技巧

C++函数指针详解与实用技巧

在C++中,**函数指针(Function Pointer)**是一种强大而灵活的工具,常用于回调机制、策略模式、事件处理等场景。本文将从概念、语法、常见用法到实战示例,带你全面掌握C++函数指针。


🧠 什么是函数指针?

函数指针本质上是一个指针,它指向一个函数的入口地址,就像普通指针指向内存中的数据一样。

例如,一个函数如下:

int add(int a, int b) {return a + b;
}

我们可以定义一个指针,指向这个函数,然后通过指针来调用它。


🧱 函数指针的基本语法

函数指针的定义语法有点绕,但遵循以下模板就能掌握:

返回类型 (*指针变量名)(参数类型列表);

add 为例,它的函数指针定义如下:

int (*funcPtr)(int, int);  // 声明函数指针
funcPtr = add;             // 指向函数
int result = funcPtr(3, 4);  // 调用函数

💡 注意:函数名本身就是指向函数的指针,add&add 等价。


🧩 函数指针的常见用途

1️⃣ 替代 if-else/switch:简化逻辑选择

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }int main() {int (*op)(int, int);char choice = '+';if (choice == '+') op = add;else if (choice == '-') op = sub;std::cout << "Result: " << op(10, 5) << std::endl;
}

2️⃣ 作为函数参数(回调机制)

void process(int a, int b, int (*op)(int, int)) {std::cout << "Result: " << op(a, b) << std::endl;
}int add(int a, int b) { return a + b; }int main() {process(3, 4, add);
}

3️⃣ 返回函数指针(高级用法)

int multiply(int a, int b) { return a * b; }int (*getOperation())(int, int) {return multiply;
}int main() {auto op = getOperation();std::cout << "Result: " << op(6, 7) << std::endl;
}

4️⃣ 使用数组存储多个函数指针(策略切换)

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }int main() {int (*ops[3])(int, int) = { add, sub, mul };int choice = 2;  // 使用第3个函数(mul)std::cout << "Result: " << ops[choice](3, 5) << std::endl;
}

🧼 函数指针 vs std::function

在现代C++中,推荐使用 std::function 来代替裸函数指针,它更安全,能包装函数、Lambda表达式、成员函数等:

#include <functional>std::function<int(int, int)> op = [](int a, int b) {return a * b;
};
std::cout << op(4, 5);  // 输出 20

🚀 如果你用的是 C++11 及以上版本,请优先考虑 std::functionLambda 表达式。


🧭 总结

特性描述
本质指向函数地址的指针
作用支持回调机制、动态策略选择
使用难点语法略显复杂,注意括号位置
推荐替代方案std::function、Lambda 表达式

函数指针虽在现代C++中使用频率下降,但在系统编程、嵌入式开发、回调机制等场景中仍有不可替代的价值。


📌 提问环节

QT中在connect函数中,第二参数使用了&对函数进行取地址,是否是多此一举呢?

答案是:不,多此一举——是必要的“好习惯”或“为了清晰性”


👇 来看这个典型用法:

QObject::connect(button, &QPushButton::clicked, this, &MyClass::onButtonClicked);

🤔 &QPushButton::clicked 为什么还要加 &,难道 QPushButton::clicked 本身不是函数指针吗?


✅ 理论上:是的,确实可以不加 &

在C++中,函数名本身就可以衰变(decay)为指针。也就是说,这样写:

QObject::connect(button, QPushButton::clicked, this, MyClass::onButtonClicked);

在部分情况下也能通过编译,但在 Qt 的宏系统(尤其是旧版本或使用 Qt 元对象编译器 moc 的语法检查)中,会产生二义性、模糊错误或编译失败。


✅ 实际上:加 & 更清晰、更兼容、更安全

  • 明确表示取地址,避免阅读歧义
  • 支持 Qt5/Qt6 的 lambda、函数指针、重载函数等一致写法
  • 对有重载信号的类,比如 QComboBox::activated,必须用 & 明确指定版本

✍ 举例(必须使用 & 才能工作):

QObject::connect(comboBox,static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),this,&MyClass::onIndexChanged);

🔔 小结:

写法是否能编译是否推荐说明
&QPushButton::clicked明确、兼容、推荐
QPushButton::clicked❌/⚠️可能模糊,非标准,易错

结论:加 & 虽然在某些情况下是“多余”的,但为了兼容性和代码清晰性,绝不是多此一举,反而是推荐做法。

http://www.xdnf.cn/news/4832.html

相关文章:

  • 15前端项目----用户信息/导航守卫
  • zst-2001 历年真题 数据库
  • [操作系统] 进程间通信:system V 信号量
  • 测试用例管理平台哪些好用?9款主流测试平台对比
  • 利用ollama.com本地部署大模型及Java验证全攻略
  • 画流程超神组合deepseek + UML
  • 力扣:多数元素
  • 计算机网络笔记(十六)——3.3使用广播信道的数据链路层
  • Oracle EBS FORM快捷键与触发器的关系与使用
  • Web 架构之前后端分离
  • Golang中集合相关的库
  • C++ 手写一个内存池
  • ollama学习-使用部署Qwen3大模型
  • 从易发性分析到灾后规划,AI大模型如何颠覆传统地质灾害防治?
  • 电厂参与全球能源效率排名的方法
  • llama.cpp win10系统无法运行,也不报错解决方案
  • NHANES指标推荐:NfL
  • 如何编写软件概要设计文档?
  • 【行业深度解析】什么是马甲包?
  • LinkList 的底层数据结构及优缺点
  • 深入理解操作系统:从基础概念到核心管理
  • 2025年排名前十进销存软件大测评
  • 12. 原生测试框架Unittest的后置处理方法的使用
  • 从零到精通:GoFrame ORM 使用指南 - 特性、实践与经验分享
  • 制作一款打飞机游戏41:敌机拖拽
  • 解析小米大模型MiMo:解锁语言模型推理潜力
  • C++核心概念全解析:从析构函数到运算符重载的深度指南
  • 「Mac畅玩AIGC与多模态25」开发篇21 - 用户画像生成与摘要输出工作流示例
  • 【大模型面试每日一题】Day 12:梯度裁剪(Gradient Clipping)的作用是什么?在Transformer中哪些场景下尤为重要?
  • 什么是采购供应链管理要点,如何实现降本增效目标